blob: 6027febb318995995822334caca9f1140b7b583b [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
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02004int 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;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020010 mbedtls_mpi_init(&actual);
Gilles Peskine71acc6e2021-05-27 22:50:53 +020011
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020012 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:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020017 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). */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020024static 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;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020032 mbedtls_mpi_init(&actual);
Gilles Peskine02db8f42021-03-30 23:28:51 +020033
34 ++mbedtls_test_info.step;
35
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020036 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. */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020041 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:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020049 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. */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020055static int check_dhm_params(const mbedtls_dhm_context *ctx,
56 size_t x_size,
57 const unsigned char *ske,
58 size_t ske_len)
Gilles Peskine02db8f42021-03-30 23:28:51 +020059{
60 size_t offset = 0;
61
62 /* Check that ctx->X and ctx->GX are within range. */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020063 TEST_ASSERT(mbedtls_mpi_cmp_int(&ctx->X, 1) > 0);
64 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&ctx->X, &ctx->P) < 0);
65 TEST_ASSERT(mbedtls_mpi_size(&ctx->X) <= x_size);
66 TEST_ASSERT(mbedtls_mpi_cmp_int(&ctx->GX, 1) > 0);
67 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&ctx->GX, &ctx->P) < 0);
Gilles Peskine02db8f42021-03-30 23:28:51 +020068
69 /* Check ske: it must contain P, G and G^X, each prefixed with a
70 * 2-byte size. */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020071 if (!check_dhm_param_output(&ctx->P, ske, ske_len, &offset))
Gilles Peskine02db8f42021-03-30 23:28:51 +020072 goto exit;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020073 if (!check_dhm_param_output(&ctx->G, ske, ske_len, &offset))
Gilles Peskine02db8f42021-03-30 23:28:51 +020074 goto exit;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020075 if (!check_dhm_param_output(&ctx->GX, ske, ske_len, &offset))
Gilles Peskine02db8f42021-03-30 23:28:51 +020076 goto exit;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020077 TEST_EQUAL(offset, ske_len);
Gilles Peskine02db8f42021-03-30 23:28:51 +020078
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020079 return 1;
Gilles Peskine02db8f42021-03-30 23:28:51 +020080exit:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020081 return 0;
Gilles Peskine02db8f42021-03-30 23:28:51 +020082}
83
Paul Bakker33b43f12013-08-20 11:48:36 +020084/* END_HEADER */
Paul Bakker5c60de22009-07-08 19:47:36 +000085
Paul Bakker33b43f12013-08-20 11:48:36 +020086/* BEGIN_DEPENDENCIES
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020087 * depends_on:MBEDTLS_DHM_C:MBEDTLS_BIGNUM_C
Paul Bakker33b43f12013-08-20 11:48:36 +020088 * END_DEPENDENCIES
89 */
Paul Bakker5690efc2011-05-26 13:16:06 +000090
Paul Bakker33b43f12013-08-20 11:48:36 +020091/* BEGIN_CASE */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020092void dhm_do_dhm(int radix_P,
93 char *input_P,
94 int x_size,
95 int radix_G,
96 char *input_G,
97 int result)
Paul Bakker5c60de22009-07-08 19:47:36 +000098{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020099 mbedtls_dhm_context ctx_srv;
100 mbedtls_dhm_context ctx_cli;
Paul Bakker5c60de22009-07-08 19:47:36 +0000101 unsigned char ske[1000];
102 unsigned char *p = ske;
103 unsigned char pub_cli[1000];
104 unsigned char sec_srv[1000];
105 unsigned char sec_cli[1000];
Paul Bakkerf4a3f302011-04-24 15:53:29 +0000106 size_t ske_len = 0;
107 size_t pub_cli_len = 0;
Manuel Pégourié-Gonnard33352052015-06-02 16:17:08 +0100108 size_t sec_srv_len;
109 size_t sec_cli_len;
Gilles Peskine2baf2b02021-03-30 23:44:22 +0200110 int i;
Ronald Cron351f0ee2020-06-10 12:12:18 +0200111 mbedtls_test_rnd_pseudo_info rnd_info;
Paul Bakker5c60de22009-07-08 19:47:36 +0000112
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200113 mbedtls_dhm_init(&ctx_srv);
114 mbedtls_dhm_init(&ctx_cli);
115 memset(ske, 0x00, 1000);
116 memset(pub_cli, 0x00, 1000);
117 memset(sec_srv, 0x00, 1000);
118 memset(sec_cli, 0x00, 1000);
119 memset(&rnd_info, 0x00, sizeof(mbedtls_test_rnd_pseudo_info));
Paul Bakker5c60de22009-07-08 19:47:36 +0000120
Manuel Pégourié-Gonnard143b5022013-09-04 16:29:59 +0200121 /*
122 * Set params
123 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200124 TEST_ASSERT(mbedtls_test_read_mpi(&ctx_srv.P, radix_P, input_P) == 0);
125 TEST_ASSERT(mbedtls_test_read_mpi(&ctx_srv.G, radix_G, input_G) == 0);
126 pub_cli_len = mbedtls_mpi_size(&ctx_srv.P);
127 TEST_ASSERT(check_get_value(&ctx_srv, MBEDTLS_DHM_PARAM_P, &ctx_srv.P));
128 TEST_ASSERT(check_get_value(&ctx_srv, MBEDTLS_DHM_PARAM_G, &ctx_srv.G));
Manuel Pégourié-Gonnard143b5022013-09-04 16:29:59 +0200129
130 /*
131 * First key exchange
132 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200133 mbedtls_test_set_step(10);
134 TEST_ASSERT(mbedtls_dhm_make_params(&ctx_srv, x_size, ske, &ske_len,
135 &mbedtls_test_rnd_pseudo_rand,
136 &rnd_info) == result);
137 if (result != 0)
Janos Follath4b151fa2017-09-20 13:46:37 +0100138 goto exit;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200139 if (!check_dhm_params(&ctx_srv, x_size, ske, ske_len))
Gilles Peskine02db8f42021-03-30 23:28:51 +0200140 goto exit;
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;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200144 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. */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200146 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
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200149 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
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200154 TEST_ASSERT(mbedtls_dhm_calc_secret(
155 &ctx_srv, sec_srv, sizeof(sec_srv), &sec_srv_len,
156 &mbedtls_test_rnd_pseudo_rand, &rnd_info) == 0);
157 TEST_ASSERT(mbedtls_dhm_calc_secret(
158 &ctx_cli, sec_cli, sizeof(sec_cli), &sec_cli_len,
159 &mbedtls_test_rnd_pseudo_rand, &rnd_info) == 0);
Manuel Pégourié-Gonnard143b5022013-09-04 16:29:59 +0200160
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200161 TEST_ASSERT(sec_srv_len == sec_cli_len);
162 TEST_ASSERT(sec_srv_len != 0);
163 TEST_ASSERT(memcmp(sec_srv, sec_cli, sec_srv_len) == 0);
Manuel Pégourié-Gonnard143b5022013-09-04 16:29:59 +0200164
Gilles Peskine71acc6e2021-05-27 22:50:53 +0200165 /* Internal value checks */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200166 TEST_ASSERT(check_get_value(&ctx_cli, MBEDTLS_DHM_PARAM_X, &ctx_cli.X));
167 TEST_ASSERT(check_get_value(&ctx_srv, MBEDTLS_DHM_PARAM_X, &ctx_srv.X));
Gilles Peskine71acc6e2021-05-27 22:50:53 +0200168 /* Cross-checks */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200169 TEST_ASSERT(check_get_value(&ctx_cli, MBEDTLS_DHM_PARAM_GX, &ctx_srv.GY));
170 TEST_ASSERT(check_get_value(&ctx_cli, MBEDTLS_DHM_PARAM_GY, &ctx_srv.GX));
171 TEST_ASSERT(check_get_value(&ctx_cli, MBEDTLS_DHM_PARAM_K, &ctx_srv.K));
172 TEST_ASSERT(check_get_value(&ctx_srv, MBEDTLS_DHM_PARAM_GX, &ctx_cli.GY));
173 TEST_ASSERT(check_get_value(&ctx_srv, MBEDTLS_DHM_PARAM_GY, &ctx_cli.GX));
174 TEST_ASSERT(check_get_value(&ctx_srv, MBEDTLS_DHM_PARAM_K, &ctx_cli.K));
Gilles Peskine71acc6e2021-05-27 22:50:53 +0200175
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200176 /* Re-do calc_secret on server a few times to test update of blinding values
177 */
178 for (i = 0; i < 3; i++) {
179 mbedtls_test_set_step(20 + i);
Manuel Pégourié-Gonnard15d5de12013-09-17 11:34:11 +0200180 sec_srv_len = 1000;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200181 TEST_ASSERT(mbedtls_dhm_calc_secret(
182 &ctx_srv, sec_srv, sizeof(sec_srv), &sec_srv_len,
183 &mbedtls_test_rnd_pseudo_rand, &rnd_info) == 0);
Manuel Pégourié-Gonnard143b5022013-09-04 16:29:59 +0200184
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200185 TEST_ASSERT(sec_srv_len == sec_cli_len);
186 TEST_ASSERT(sec_srv_len != 0);
187 TEST_ASSERT(memcmp(sec_srv, sec_cli, sec_srv_len) == 0);
Manuel Pégourié-Gonnard15d5de12013-09-17 11:34:11 +0200188 }
Manuel Pégourié-Gonnard143b5022013-09-04 16:29:59 +0200189
190 /*
191 * Second key exchange to test change of blinding values on server
192 */
Manuel Pégourié-Gonnard143b5022013-09-04 16:29:59 +0200193 p = ske;
Paul Bakker5c60de22009-07-08 19:47:36 +0000194
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200195 mbedtls_test_set_step(30);
196 TEST_ASSERT(mbedtls_dhm_make_params(&ctx_srv, x_size, ske, &ske_len,
197 &mbedtls_test_rnd_pseudo_rand,
198 &rnd_info) == 0);
199 if (!check_dhm_params(&ctx_srv, x_size, ske, ske_len))
Gilles Peskine02db8f42021-03-30 23:28:51 +0200200 goto exit;
Paul Bakker5c60de22009-07-08 19:47:36 +0000201 ske[ske_len++] = 0;
202 ske[ske_len++] = 0;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200203 TEST_ASSERT(mbedtls_dhm_read_params(&ctx_cli, &p, ske + ske_len) == 0);
Paul Bakker5c60de22009-07-08 19:47:36 +0000204
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200205 TEST_ASSERT(mbedtls_dhm_make_public(&ctx_cli, x_size, pub_cli, pub_cli_len,
206 &mbedtls_test_rnd_pseudo_rand,
207 &rnd_info) == 0);
208 TEST_ASSERT(mbedtls_dhm_read_public(&ctx_srv, pub_cli, pub_cli_len) == 0);
Paul Bakker5c60de22009-07-08 19:47:36 +0000209
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200210 TEST_ASSERT(mbedtls_dhm_calc_secret(
211 &ctx_srv, sec_srv, sizeof(sec_srv), &sec_srv_len,
212 &mbedtls_test_rnd_pseudo_rand, &rnd_info) == 0);
213 TEST_ASSERT(mbedtls_dhm_calc_secret(
214 &ctx_cli, sec_cli, sizeof(sec_cli), &sec_cli_len,
215 &mbedtls_test_rnd_pseudo_rand, &rnd_info) == 0);
Paul Bakker5c60de22009-07-08 19:47:36 +0000216
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200217 TEST_ASSERT(sec_srv_len == sec_cli_len);
218 TEST_ASSERT(sec_srv_len != 0);
219 TEST_ASSERT(memcmp(sec_srv, sec_cli, sec_srv_len) == 0);
Paul Bakkerc43481a2011-02-20 16:34:26 +0000220
Paul Bakkerbd51b262014-07-10 15:26:12 +0200221exit:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200222 mbedtls_dhm_free(&ctx_srv);
223 mbedtls_dhm_free(&ctx_cli);
Paul Bakker5c60de22009-07-08 19:47:36 +0000224}
Paul Bakker33b43f12013-08-20 11:48:36 +0200225/* END_CASE */
Paul Bakker40ce79f2013-09-15 17:43:54 +0200226
Chris Jonesd10b3312020-12-02 10:41:50 +0000227/* BEGIN_CASE */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200228void dhm_make_public(int P_bytes, int radix_G, char *input_G, int result)
Chris Jonesd10b3312020-12-02 10:41:50 +0000229{
230 mbedtls_mpi P, G;
231 mbedtls_dhm_context ctx;
232 unsigned char output[MBEDTLS_MPI_MAX_SIZE];
233
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200234 mbedtls_mpi_init(&P);
235 mbedtls_mpi_init(&G);
236 mbedtls_dhm_init(&ctx);
Chris Jonesd10b3312020-12-02 10:41:50 +0000237
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200238 TEST_ASSERT(mbedtls_mpi_lset(&P, 1) == 0);
239 TEST_ASSERT(mbedtls_mpi_shift_l(&P, (P_bytes * 8) - 1) == 0);
240 TEST_ASSERT(mbedtls_mpi_set_bit(&P, 0, 1) == 0);
Chris Jonesd10b3312020-12-02 10:41:50 +0000241
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200242 TEST_ASSERT(mbedtls_test_read_mpi(&G, radix_G, input_G) == 0);
Chris Jonesd10b3312020-12-02 10:41:50 +0000243
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200244 TEST_ASSERT(mbedtls_dhm_set_group(&ctx, &P, &G) == 0);
245 TEST_ASSERT(mbedtls_dhm_make_public(
246 &ctx, (int)mbedtls_mpi_size(&P), output, sizeof(output),
247 &mbedtls_test_rnd_pseudo_rand, NULL) == result);
Chris Jonesd10b3312020-12-02 10:41:50 +0000248
249exit:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200250 mbedtls_mpi_free(&P);
251 mbedtls_mpi_free(&G);
252 mbedtls_dhm_free(&ctx);
Chris Jonesd10b3312020-12-02 10:41:50 +0000253}
254/* END_CASE */
255
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200256/* BEGIN_CASE depends_on:MBEDTLS_FS_IO */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200257void dhm_file(char *filename, char *p, char *g, int len)
Manuel Pégourié-Gonnard3fec2202014-03-29 16:42:38 +0100258{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200259 mbedtls_dhm_context ctx;
260 mbedtls_mpi P, G;
Manuel Pégourié-Gonnard3fec2202014-03-29 16:42:38 +0100261
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200262 mbedtls_dhm_init(&ctx);
263 mbedtls_mpi_init(&P);
264 mbedtls_mpi_init(&G);
Manuel Pégourié-Gonnard3fec2202014-03-29 16:42:38 +0100265
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200266 TEST_ASSERT(mbedtls_test_read_mpi(&P, 16, p) == 0);
267 TEST_ASSERT(mbedtls_test_read_mpi(&G, 16, g) == 0);
Manuel Pégourié-Gonnard3fec2202014-03-29 16:42:38 +0100268
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200269 TEST_ASSERT(mbedtls_dhm_parse_dhmfile(&ctx, filename) == 0);
Manuel Pégourié-Gonnard3fec2202014-03-29 16:42:38 +0100270
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200271 TEST_EQUAL(mbedtls_dhm_get_len(&ctx), (size_t)len);
272 TEST_EQUAL(mbedtls_dhm_get_bitlen(&ctx), mbedtls_mpi_bitlen(&P));
273 TEST_ASSERT(check_get_value(&ctx, MBEDTLS_DHM_PARAM_P, &P));
274 TEST_ASSERT(check_get_value(&ctx, MBEDTLS_DHM_PARAM_G, &G));
Manuel Pégourié-Gonnard3fec2202014-03-29 16:42:38 +0100275
Paul Bakkerbd51b262014-07-10 15:26:12 +0200276exit:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200277 mbedtls_mpi_free(&P);
278 mbedtls_mpi_free(&G);
279 mbedtls_dhm_free(&ctx);
Manuel Pégourié-Gonnard3fec2202014-03-29 16:42:38 +0100280}
281/* END_CASE */
282
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200283/* BEGIN_CASE depends_on:MBEDTLS_SELF_TEST */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200284void dhm_selftest()
Paul Bakker40ce79f2013-09-15 17:43:54 +0200285{
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200286 TEST_ASSERT(mbedtls_dhm_self_test(1) == 0);
Paul Bakker40ce79f2013-09-15 17:43:54 +0200287}
288/* END_CASE */