blob: 94137a264d749d416d8ce54827c956d9b1b2bdc1 [file] [log] [blame]
Paul Bakker5121ce52009-01-03 21:22:43 +00001/*
2 * Diffie-Hellman-Merkle key exchange
3 *
Bence Szépkúti1e148272020-08-07 13:07:28 +02004 * Copyright The Mbed TLS Contributors
Manuel Pégourié-Gonnard37ff1402015-09-04 14:21:07 +02005 * SPDX-License-Identifier: Apache-2.0
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License"); you may
8 * not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
15 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
Paul Bakker5121ce52009-01-03 21:22:43 +000018 */
19/*
Simon Butcherbdae02c2016-01-20 00:44:42 +000020 * The following sources were referenced in the design of this implementation
21 * of the Diffie-Hellman-Merkle algorithm:
Paul Bakker5121ce52009-01-03 21:22:43 +000022 *
Simon Butcherbdae02c2016-01-20 00:44:42 +000023 * [1] Handbook of Applied Cryptography - 1997, Chapter 12
24 * Menezes, van Oorschot and Vanstone
25 *
Paul Bakker5121ce52009-01-03 21:22:43 +000026 */
27
Gilles Peskinedb09ef62020-06-03 01:43:33 +020028#include "common.h"
Paul Bakker5121ce52009-01-03 21:22:43 +000029
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020030#if defined(MBEDTLS_DHM_C)
Paul Bakker5121ce52009-01-03 21:22:43 +000031
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000032#include "mbedtls/dhm.h"
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -050033#include "mbedtls/platform_util.h"
Janos Follath24eed8d2019-11-22 13:21:35 +000034#include "mbedtls/error.h"
Paul Bakker5121ce52009-01-03 21:22:43 +000035
Rich Evans00ab4702015-02-06 13:43:58 +000036#include <string.h>
37
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020038#if defined(MBEDTLS_PEM_PARSE_C)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000039#include "mbedtls/pem.h"
Paul Bakker40ce79f2013-09-15 17:43:54 +020040#endif
41
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020042#if defined(MBEDTLS_ASN1_PARSE_C)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000043#include "mbedtls/asn1.h"
Paul Bakker40ce79f2013-09-15 17:43:54 +020044#endif
45
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000046#include "mbedtls/platform.h"
Paul Bakker40ce79f2013-09-15 17:43:54 +020047
Reuven Levin1f35ca92017-12-07 10:09:32 +000048#if !defined(MBEDTLS_DHM_ALT)
Paul Bakker34617722014-06-13 17:20:13 +020049
Paul Bakker5121ce52009-01-03 21:22:43 +000050/*
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020051 * helper to validate the mbedtls_mpi size and import it
Paul Bakker5121ce52009-01-03 21:22:43 +000052 */
David Horstmann71159f42023-01-03 12:51:59 +000053static int dhm_read_bignum(mbedtls_mpi *X,
54 unsigned char **p,
55 const unsigned char *end)
Paul Bakker5121ce52009-01-03 21:22:43 +000056{
57 int ret, n;
58
David Horstmann71159f42023-01-03 12:51:59 +000059 if (end - *p < 2) {
60 return MBEDTLS_ERR_DHM_BAD_INPUT_DATA;
61 }
Paul Bakker5121ce52009-01-03 21:22:43 +000062
David Horstmann71159f42023-01-03 12:51:59 +000063 n = ((*p)[0] << 8) | (*p)[1];
Paul Bakker5121ce52009-01-03 21:22:43 +000064 (*p) += 2;
65
David Horstmann71159f42023-01-03 12:51:59 +000066 if ((int) (end - *p) < n) {
67 return MBEDTLS_ERR_DHM_BAD_INPUT_DATA;
68 }
Paul Bakker5121ce52009-01-03 21:22:43 +000069
David Horstmann71159f42023-01-03 12:51:59 +000070 if ((ret = mbedtls_mpi_read_binary(X, *p, n)) != 0) {
71 return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_DHM_READ_PARAMS_FAILED, ret);
72 }
Paul Bakker5121ce52009-01-03 21:22:43 +000073
74 (*p) += n;
75
David Horstmann71159f42023-01-03 12:51:59 +000076 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +000077}
78
79/*
Paul Bakkeraec37cb2012-04-26 18:59:59 +000080 * Verify sanity of parameter with regards to P
Paul Bakker345a6fe2011-02-28 21:20:02 +000081 *
Paul Bakkeraec37cb2012-04-26 18:59:59 +000082 * Parameter should be: 2 <= public_param <= P - 2
Paul Bakker345a6fe2011-02-28 21:20:02 +000083 *
Janos Follathaa325d72017-09-20 15:33:24 +010084 * This means that we need to return an error if
Janos Follath1ad1c6d2017-09-21 09:02:11 +010085 * public_param < 2 or public_param > P-2
Janos Follathaa325d72017-09-20 15:33:24 +010086 *
Paul Bakker345a6fe2011-02-28 21:20:02 +000087 * For more information on the attack, see:
88 * http://www.cl.cam.ac.uk/~rja14/Papers/psandqs.pdf
89 * http://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2005-2643
Paul Bakkerc47840e2011-02-20 16:37:30 +000090 */
David Horstmann71159f42023-01-03 12:51:59 +000091static int dhm_check_range(const mbedtls_mpi *param, const mbedtls_mpi *P)
Paul Bakkerc47840e2011-02-20 16:37:30 +000092{
Gilles Peskine8e38acc2021-03-31 22:56:43 +020093 mbedtls_mpi U;
Janos Follathaa325d72017-09-20 15:33:24 +010094 int ret = 0;
Paul Bakkerc47840e2011-02-20 16:37:30 +000095
David Horstmann71159f42023-01-03 12:51:59 +000096 mbedtls_mpi_init(&U);
Paul Bakker3d8fb632014-04-17 12:42:41 +020097
David Horstmann71159f42023-01-03 12:51:59 +000098 MBEDTLS_MPI_CHK(mbedtls_mpi_sub_int(&U, P, 2));
Paul Bakkerc47840e2011-02-20 16:37:30 +000099
David Horstmann71159f42023-01-03 12:51:59 +0000100 if (mbedtls_mpi_cmp_int(param, 2) < 0 ||
101 mbedtls_mpi_cmp_mpi(param, &U) > 0) {
Janos Follathaa325d72017-09-20 15:33:24 +0100102 ret = MBEDTLS_ERR_DHM_BAD_INPUT_DATA;
Paul Bakkerc47840e2011-02-20 16:37:30 +0000103 }
104
Paul Bakker3d8fb632014-04-17 12:42:41 +0200105cleanup:
David Horstmann71159f42023-01-03 12:51:59 +0000106 mbedtls_mpi_free(&U);
107 return ret;
Paul Bakkerc47840e2011-02-20 16:37:30 +0000108}
109
David Horstmann71159f42023-01-03 12:51:59 +0000110void mbedtls_dhm_init(mbedtls_dhm_context *ctx)
Paul Bakker8f870b02014-06-20 13:32:38 +0200111{
David Horstmann71159f42023-01-03 12:51:59 +0000112 memset(ctx, 0, sizeof(mbedtls_dhm_context));
Paul Bakker8f870b02014-06-20 13:32:38 +0200113}
114
David Horstmann71159f42023-01-03 12:51:59 +0000115size_t mbedtls_dhm_get_bitlen(const mbedtls_dhm_context *ctx)
Gilles Peskine487bbf62021-05-27 22:17:07 +0200116{
David Horstmann71159f42023-01-03 12:51:59 +0000117 return mbedtls_mpi_bitlen(&ctx->P);
Gilles Peskine487bbf62021-05-27 22:17:07 +0200118}
119
David Horstmann71159f42023-01-03 12:51:59 +0000120size_t mbedtls_dhm_get_len(const mbedtls_dhm_context *ctx)
Gilles Peskine487bbf62021-05-27 22:17:07 +0200121{
David Horstmann71159f42023-01-03 12:51:59 +0000122 return mbedtls_mpi_size(&ctx->P);
Gilles Peskine487bbf62021-05-27 22:17:07 +0200123}
124
David Horstmann71159f42023-01-03 12:51:59 +0000125int mbedtls_dhm_get_value(const mbedtls_dhm_context *ctx,
126 mbedtls_dhm_parameter param,
127 mbedtls_mpi *dest)
Gilles Peskine71acc6e2021-05-27 22:50:53 +0200128{
129 const mbedtls_mpi *src = NULL;
David Horstmann71159f42023-01-03 12:51:59 +0000130 switch (param) {
Gilles Peskine71acc6e2021-05-27 22:50:53 +0200131 case MBEDTLS_DHM_PARAM_P:
132 src = &ctx->P;
133 break;
134 case MBEDTLS_DHM_PARAM_G:
135 src = &ctx->G;
136 break;
137 case MBEDTLS_DHM_PARAM_X:
138 src = &ctx->X;
139 break;
140 case MBEDTLS_DHM_PARAM_GX:
141 src = &ctx->GX;
142 break;
143 case MBEDTLS_DHM_PARAM_GY:
144 src = &ctx->GY;
145 break;
146 case MBEDTLS_DHM_PARAM_K:
147 src = &ctx->K;
148 break;
149 default:
David Horstmann71159f42023-01-03 12:51:59 +0000150 return MBEDTLS_ERR_DHM_BAD_INPUT_DATA;
Gilles Peskine71acc6e2021-05-27 22:50:53 +0200151 }
David Horstmann71159f42023-01-03 12:51:59 +0000152 return mbedtls_mpi_copy(dest, src);
Gilles Peskine71acc6e2021-05-27 22:50:53 +0200153}
154
Paul Bakkerc47840e2011-02-20 16:37:30 +0000155/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000156 * Parse the ServerKeyExchange parameters
157 */
David Horstmann71159f42023-01-03 12:51:59 +0000158int mbedtls_dhm_read_params(mbedtls_dhm_context *ctx,
159 unsigned char **p,
160 const unsigned char *end)
Paul Bakker5121ce52009-01-03 21:22:43 +0000161{
Janos Follath24eed8d2019-11-22 13:21:35 +0000162 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker5121ce52009-01-03 21:22:43 +0000163
David Horstmann71159f42023-01-03 12:51:59 +0000164 if ((ret = dhm_read_bignum(&ctx->P, p, end)) != 0 ||
165 (ret = dhm_read_bignum(&ctx->G, p, end)) != 0 ||
166 (ret = dhm_read_bignum(&ctx->GY, p, end)) != 0) {
167 return ret;
168 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000169
David Horstmann71159f42023-01-03 12:51:59 +0000170 if ((ret = dhm_check_range(&ctx->GY, &ctx->P)) != 0) {
171 return ret;
172 }
Paul Bakker345a6fe2011-02-28 21:20:02 +0000173
David Horstmann71159f42023-01-03 12:51:59 +0000174 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000175}
176
Gilles Peskine17f1a262021-03-31 22:48:14 +0200177/*
Gilles Peskineda7ee012021-03-31 23:04:50 +0200178 * Pick a random R in the range [2, M-2] for blinding or key generation.
Gilles Peskine17f1a262021-03-31 22:48:14 +0200179 */
David Horstmann71159f42023-01-03 12:51:59 +0000180static int dhm_random_below(mbedtls_mpi *R, const mbedtls_mpi *M,
181 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng)
Gilles Peskine17f1a262021-03-31 22:48:14 +0200182{
Gilles Peskineda7ee012021-03-31 23:04:50 +0200183 int ret;
Gilles Peskine17f1a262021-03-31 22:48:14 +0200184
David Horstmann71159f42023-01-03 12:51:59 +0000185 MBEDTLS_MPI_CHK(mbedtls_mpi_random(R, 3, M, f_rng, p_rng));
186 MBEDTLS_MPI_CHK(mbedtls_mpi_sub_int(R, R, 1));
Gilles Peskine17f1a262021-03-31 22:48:14 +0200187
188cleanup:
David Horstmann71159f42023-01-03 12:51:59 +0000189 return ret;
Gilles Peskine17f1a262021-03-31 22:48:14 +0200190}
191
David Horstmann71159f42023-01-03 12:51:59 +0000192static int dhm_make_common(mbedtls_dhm_context *ctx, int x_size,
193 int (*f_rng)(void *, unsigned char *, size_t),
194 void *p_rng)
Paul Bakker5121ce52009-01-03 21:22:43 +0000195{
Gilles Peskine17f1a262021-03-31 22:48:14 +0200196 int ret = 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000197
David Horstmann71159f42023-01-03 12:51:59 +0000198 if (mbedtls_mpi_cmp_int(&ctx->P, 0) == 0) {
199 return MBEDTLS_ERR_DHM_BAD_INPUT_DATA;
Paul Bakkeraec37cb2012-04-26 18:59:59 +0000200 }
David Horstmann71159f42023-01-03 12:51:59 +0000201 if (x_size < 0) {
202 return MBEDTLS_ERR_DHM_BAD_INPUT_DATA;
203 }
204
205 if ((unsigned) x_size < mbedtls_mpi_size(&ctx->P)) {
206 MBEDTLS_MPI_CHK(mbedtls_mpi_fill_random(&ctx->X, x_size, f_rng, p_rng));
207 } else {
Gilles Peskine17f1a262021-03-31 22:48:14 +0200208 /* Generate X as large as possible ( <= P - 2 ) */
David Horstmann71159f42023-01-03 12:51:59 +0000209 ret = dhm_random_below(&ctx->X, &ctx->P, f_rng, p_rng);
210 if (ret == MBEDTLS_ERR_MPI_NOT_ACCEPTABLE) {
211 return MBEDTLS_ERR_DHM_MAKE_PARAMS_FAILED;
212 }
213 if (ret != 0) {
214 return ret;
215 }
Gilles Peskine17f1a262021-03-31 22:48:14 +0200216 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000217
Paul Bakkerff7fe672010-07-18 09:45:05 +0000218 /*
219 * Calculate GX = G^X mod P
220 */
David Horstmann71159f42023-01-03 12:51:59 +0000221 MBEDTLS_MPI_CHK(mbedtls_mpi_exp_mod(&ctx->GX, &ctx->G, &ctx->X,
222 &ctx->P, &ctx->RP));
Paul Bakker5121ce52009-01-03 21:22:43 +0000223
David Horstmann71159f42023-01-03 12:51:59 +0000224 if ((ret = dhm_check_range(&ctx->GX, &ctx->P)) != 0) {
225 return ret;
226 }
Paul Bakkerc47840e2011-02-20 16:37:30 +0000227
Gilles Peskinecb660f22021-03-31 22:35:13 +0200228cleanup:
David Horstmann71159f42023-01-03 12:51:59 +0000229 return ret;
Gilles Peskinecb660f22021-03-31 22:35:13 +0200230}
231
232/*
233 * Setup and write the ServerKeyExchange parameters
234 */
David Horstmann71159f42023-01-03 12:51:59 +0000235int mbedtls_dhm_make_params(mbedtls_dhm_context *ctx, int x_size,
236 unsigned char *output, size_t *olen,
237 int (*f_rng)(void *, unsigned char *, size_t),
238 void *p_rng)
Gilles Peskinecb660f22021-03-31 22:35:13 +0200239{
240 int ret;
241 size_t n1, n2, n3;
242 unsigned char *p;
Gilles Peskinecb660f22021-03-31 22:35:13 +0200243
David Horstmann71159f42023-01-03 12:51:59 +0000244 ret = dhm_make_common(ctx, x_size, f_rng, p_rng);
245 if (ret != 0) {
Gilles Peskinecb660f22021-03-31 22:35:13 +0200246 goto cleanup;
David Horstmann71159f42023-01-03 12:51:59 +0000247 }
Gilles Peskinecb660f22021-03-31 22:35:13 +0200248
Paul Bakker5121ce52009-01-03 21:22:43 +0000249 /*
Gilles Peskine03299dc2021-04-13 22:10:24 +0200250 * Export P, G, GX. RFC 5246 §4.4 states that "leading zero octets are
251 * not required". We omit leading zeros for compactness.
Paul Bakker5121ce52009-01-03 21:22:43 +0000252 */
David Horstmann71159f42023-01-03 12:51:59 +0000253#define DHM_MPI_EXPORT(X, n) \
Hanno Beckere71ad122017-09-28 10:32:25 +0100254 do { \
David Horstmann71159f42023-01-03 12:51:59 +0000255 MBEDTLS_MPI_CHK(mbedtls_mpi_write_binary((X), \
256 p + 2, \
257 (n))); \
258 *p++ = MBEDTLS_BYTE_1(n); \
259 *p++ = MBEDTLS_BYTE_0(n); \
260 p += (n); \
261 } while (0)
Paul Bakker5121ce52009-01-03 21:22:43 +0000262
David Horstmann71159f42023-01-03 12:51:59 +0000263 n1 = mbedtls_mpi_size(&ctx->P);
264 n2 = mbedtls_mpi_size(&ctx->G);
265 n3 = mbedtls_mpi_size(&ctx->GX);
Paul Bakker5121ce52009-01-03 21:22:43 +0000266
267 p = output;
David Horstmann71159f42023-01-03 12:51:59 +0000268 DHM_MPI_EXPORT(&ctx->P, n1);
269 DHM_MPI_EXPORT(&ctx->G, n2);
270 DHM_MPI_EXPORT(&ctx->GX, n3);
Paul Bakker5121ce52009-01-03 21:22:43 +0000271
Hanno Beckere71ad122017-09-28 10:32:25 +0100272 *olen = p - output;
Paul Bakker5121ce52009-01-03 21:22:43 +0000273
Paul Bakker5121ce52009-01-03 21:22:43 +0000274cleanup:
David Horstmann71159f42023-01-03 12:51:59 +0000275 if (ret != 0 && ret > -128) {
276 ret = MBEDTLS_ERROR_ADD(MBEDTLS_ERR_DHM_MAKE_PARAMS_FAILED, ret);
277 }
278 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +0000279}
280
281/*
Hanno Becker8880e752017-10-04 13:15:08 +0100282 * Set prime modulus and generator
283 */
David Horstmann71159f42023-01-03 12:51:59 +0000284int mbedtls_dhm_set_group(mbedtls_dhm_context *ctx,
285 const mbedtls_mpi *P,
286 const mbedtls_mpi *G)
Hanno Becker8880e752017-10-04 13:15:08 +0100287{
Janos Follath24eed8d2019-11-22 13:21:35 +0000288 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Hanno Becker8880e752017-10-04 13:15:08 +0100289
David Horstmann71159f42023-01-03 12:51:59 +0000290 if ((ret = mbedtls_mpi_copy(&ctx->P, P)) != 0 ||
291 (ret = mbedtls_mpi_copy(&ctx->G, G)) != 0) {
292 return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_DHM_SET_GROUP_FAILED, ret);
Hanno Becker8880e752017-10-04 13:15:08 +0100293 }
294
David Horstmann71159f42023-01-03 12:51:59 +0000295 return 0;
Hanno Becker8880e752017-10-04 13:15:08 +0100296}
297
298/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000299 * Import the peer's public value G^Y
300 */
David Horstmann71159f42023-01-03 12:51:59 +0000301int mbedtls_dhm_read_public(mbedtls_dhm_context *ctx,
302 const unsigned char *input, size_t ilen)
Paul Bakker5121ce52009-01-03 21:22:43 +0000303{
Janos Follath24eed8d2019-11-22 13:21:35 +0000304 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker5121ce52009-01-03 21:22:43 +0000305
David Horstmann71159f42023-01-03 12:51:59 +0000306 if (ilen < 1 || ilen > mbedtls_dhm_get_len(ctx)) {
307 return MBEDTLS_ERR_DHM_BAD_INPUT_DATA;
308 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000309
David Horstmann71159f42023-01-03 12:51:59 +0000310 if ((ret = mbedtls_mpi_read_binary(&ctx->GY, input, ilen)) != 0) {
311 return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_DHM_READ_PUBLIC_FAILED, ret);
312 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000313
David Horstmann71159f42023-01-03 12:51:59 +0000314 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000315}
316
317/*
318 * Create own private value X and export G^X
319 */
David Horstmann71159f42023-01-03 12:51:59 +0000320int mbedtls_dhm_make_public(mbedtls_dhm_context *ctx, int x_size,
321 unsigned char *output, size_t olen,
322 int (*f_rng)(void *, unsigned char *, size_t),
323 void *p_rng)
Paul Bakker5121ce52009-01-03 21:22:43 +0000324{
Gilles Peskinecb660f22021-03-31 22:35:13 +0200325 int ret;
Paul Bakker5121ce52009-01-03 21:22:43 +0000326
David Horstmann71159f42023-01-03 12:51:59 +0000327 if (olen < 1 || olen > mbedtls_dhm_get_len(ctx)) {
328 return MBEDTLS_ERR_DHM_BAD_INPUT_DATA;
329 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000330
David Horstmann71159f42023-01-03 12:51:59 +0000331 ret = dhm_make_common(ctx, x_size, f_rng, p_rng);
332 if (ret == MBEDTLS_ERR_DHM_MAKE_PARAMS_FAILED) {
333 return MBEDTLS_ERR_DHM_MAKE_PUBLIC_FAILED;
334 }
335 if (ret != 0) {
Gilles Peskinecb660f22021-03-31 22:35:13 +0200336 goto cleanup;
David Horstmann71159f42023-01-03 12:51:59 +0000337 }
Paul Bakkerc47840e2011-02-20 16:37:30 +0000338
David Horstmann71159f42023-01-03 12:51:59 +0000339 MBEDTLS_MPI_CHK(mbedtls_mpi_write_binary(&ctx->GX, output, olen));
Paul Bakker5121ce52009-01-03 21:22:43 +0000340
341cleanup:
David Horstmann71159f42023-01-03 12:51:59 +0000342 if (ret != 0 && ret > -128) {
343 ret = MBEDTLS_ERROR_ADD(MBEDTLS_ERR_DHM_MAKE_PUBLIC_FAILED, ret);
344 }
345 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +0000346}
347
Manuel Pégourié-Gonnard9f58c4b2020-06-25 12:34:58 +0200348
349/*
Manuel Pégourié-Gonnard143b5022013-09-04 16:29:59 +0200350 * Use the blinding method and optimisation suggested in section 10 of:
351 * KOCHER, Paul C. Timing attacks on implementations of Diffie-Hellman, RSA,
Manuel Pégourié-Gonnard998930a2015-04-03 13:48:06 +0200352 * DSS, and other systems. In : Advances in Cryptology-CRYPTO'96. Springer
Manuel Pégourié-Gonnard143b5022013-09-04 16:29:59 +0200353 * Berlin Heidelberg, 1996. p. 104-113.
354 */
David Horstmann71159f42023-01-03 12:51:59 +0000355static int dhm_update_blinding(mbedtls_dhm_context *ctx,
356 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng)
Manuel Pégourié-Gonnard143b5022013-09-04 16:29:59 +0200357{
Manuel Pégourié-Gonnard9f58c4b2020-06-25 12:34:58 +0200358 int ret;
Manuel Pégourié-Gonnardaf721672020-06-25 12:47:22 +0200359 mbedtls_mpi R;
360
David Horstmann71159f42023-01-03 12:51:59 +0000361 mbedtls_mpi_init(&R);
Manuel Pégourié-Gonnard143b5022013-09-04 16:29:59 +0200362
363 /*
Manuel Pégourié-Gonnard15d5de12013-09-17 11:34:11 +0200364 * Don't use any blinding the first time a particular X is used,
365 * but remember it to use blinding next time.
Manuel Pégourié-Gonnard143b5022013-09-04 16:29:59 +0200366 */
David Horstmann71159f42023-01-03 12:51:59 +0000367 if (mbedtls_mpi_cmp_mpi(&ctx->X, &ctx->pX) != 0) {
368 MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&ctx->pX, &ctx->X));
369 MBEDTLS_MPI_CHK(mbedtls_mpi_lset(&ctx->Vi, 1));
370 MBEDTLS_MPI_CHK(mbedtls_mpi_lset(&ctx->Vf, 1));
Manuel Pégourié-Gonnarded8a02b2013-09-04 16:39:03 +0200371
David Horstmann71159f42023-01-03 12:51:59 +0000372 return 0;
Manuel Pégourié-Gonnard143b5022013-09-04 16:29:59 +0200373 }
374
375 /*
Manuel Pégourié-Gonnard15d5de12013-09-17 11:34:11 +0200376 * Ok, we need blinding. Can we re-use existing values?
377 * If yes, just update them by squaring them.
Manuel Pégourié-Gonnard143b5022013-09-04 16:29:59 +0200378 */
David Horstmann71159f42023-01-03 12:51:59 +0000379 if (mbedtls_mpi_cmp_int(&ctx->Vi, 1) != 0) {
380 MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(&ctx->Vi, &ctx->Vi, &ctx->Vi));
381 MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(&ctx->Vi, &ctx->Vi, &ctx->P));
Manuel Pégourié-Gonnard15d5de12013-09-17 11:34:11 +0200382
David Horstmann71159f42023-01-03 12:51:59 +0000383 MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(&ctx->Vf, &ctx->Vf, &ctx->Vf));
384 MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(&ctx->Vf, &ctx->Vf, &ctx->P));
Manuel Pégourié-Gonnard15d5de12013-09-17 11:34:11 +0200385
David Horstmann71159f42023-01-03 12:51:59 +0000386 return 0;
Manuel Pégourié-Gonnard15d5de12013-09-17 11:34:11 +0200387 }
388
389 /*
390 * We need to generate blinding values from scratch
391 */
392
Gilles Peskine7b2b66e2021-03-31 22:50:57 +0200393 /* Vi = random( 2, P-2 ) */
David Horstmann71159f42023-01-03 12:51:59 +0000394 MBEDTLS_MPI_CHK(dhm_random_below(&ctx->Vi, &ctx->P, f_rng, p_rng));
Manuel Pégourié-Gonnard15d5de12013-09-17 11:34:11 +0200395
Manuel Pégourié-Gonnardaf721672020-06-25 12:47:22 +0200396 /* Vf = Vi^-X mod P
397 * First compute Vi^-1 = R * (R Vi)^-1, (avoiding leaks from inv_mod),
398 * then elevate to the Xth power. */
David Horstmann71159f42023-01-03 12:51:59 +0000399 MBEDTLS_MPI_CHK(dhm_random_below(&R, &ctx->P, f_rng, p_rng));
400 MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(&ctx->Vf, &ctx->Vi, &R));
401 MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(&ctx->Vf, &ctx->Vf, &ctx->P));
402 MBEDTLS_MPI_CHK(mbedtls_mpi_inv_mod(&ctx->Vf, &ctx->Vf, &ctx->P));
403 MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(&ctx->Vf, &ctx->Vf, &R));
404 MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(&ctx->Vf, &ctx->Vf, &ctx->P));
Manuel Pégourié-Gonnard15d5de12013-09-17 11:34:11 +0200405
David Horstmann71159f42023-01-03 12:51:59 +0000406 MBEDTLS_MPI_CHK(mbedtls_mpi_exp_mod(&ctx->Vf, &ctx->Vf, &ctx->X, &ctx->P, &ctx->RP));
Manuel Pégourié-Gonnard143b5022013-09-04 16:29:59 +0200407
Manuel Pégourié-Gonnard143b5022013-09-04 16:29:59 +0200408cleanup:
David Horstmann71159f42023-01-03 12:51:59 +0000409 mbedtls_mpi_free(&R);
Manuel Pégourié-Gonnardaf721672020-06-25 12:47:22 +0200410
David Horstmann71159f42023-01-03 12:51:59 +0000411 return ret;
Manuel Pégourié-Gonnard143b5022013-09-04 16:29:59 +0200412}
413
414/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000415 * Derive and export the shared secret (G^Y)^X mod P
416 */
David Horstmann71159f42023-01-03 12:51:59 +0000417int mbedtls_dhm_calc_secret(mbedtls_dhm_context *ctx,
418 unsigned char *output, size_t output_size, size_t *olen,
419 int (*f_rng)(void *, unsigned char *, size_t),
420 void *p_rng)
Paul Bakker5121ce52009-01-03 21:22:43 +0000421{
Janos Follath24eed8d2019-11-22 13:21:35 +0000422 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200423 mbedtls_mpi GYb;
Manuel Pégourié-Gonnard2d627642013-09-04 14:22:07 +0200424
David Horstmann71159f42023-01-03 12:51:59 +0000425 if (f_rng == NULL) {
426 return MBEDTLS_ERR_DHM_BAD_INPUT_DATA;
427 }
Manuel Pégourié-Gonnard1a877222021-06-15 11:29:26 +0200428
David Horstmann71159f42023-01-03 12:51:59 +0000429 if (output_size < mbedtls_dhm_get_len(ctx)) {
430 return MBEDTLS_ERR_DHM_BAD_INPUT_DATA;
431 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000432
David Horstmann71159f42023-01-03 12:51:59 +0000433 if ((ret = dhm_check_range(&ctx->GY, &ctx->P)) != 0) {
434 return ret;
435 }
Paul Bakkerc47840e2011-02-20 16:37:30 +0000436
David Horstmann71159f42023-01-03 12:51:59 +0000437 mbedtls_mpi_init(&GYb);
Manuel Pégourié-Gonnard143b5022013-09-04 16:29:59 +0200438
439 /* Blind peer's value */
David Horstmann71159f42023-01-03 12:51:59 +0000440 MBEDTLS_MPI_CHK(dhm_update_blinding(ctx, f_rng, p_rng));
441 MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(&GYb, &ctx->GY, &ctx->Vi));
442 MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(&GYb, &GYb, &ctx->P));
Manuel Pégourié-Gonnard143b5022013-09-04 16:29:59 +0200443
444 /* Do modular exponentiation */
David Horstmann71159f42023-01-03 12:51:59 +0000445 MBEDTLS_MPI_CHK(mbedtls_mpi_exp_mod(&ctx->K, &GYb, &ctx->X,
446 &ctx->P, &ctx->RP));
Manuel Pégourié-Gonnard143b5022013-09-04 16:29:59 +0200447
448 /* Unblind secret value */
David Horstmann71159f42023-01-03 12:51:59 +0000449 MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(&ctx->K, &ctx->K, &ctx->Vf));
450 MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(&ctx->K, &ctx->K, &ctx->P));
Manuel Pégourié-Gonnard143b5022013-09-04 16:29:59 +0200451
Gilles Peskine03299dc2021-04-13 22:10:24 +0200452 /* Output the secret without any leading zero byte. This is mandatory
453 * for TLS per RFC 5246 §8.1.2. */
David Horstmann71159f42023-01-03 12:51:59 +0000454 *olen = mbedtls_mpi_size(&ctx->K);
455 MBEDTLS_MPI_CHK(mbedtls_mpi_write_binary(&ctx->K, output, *olen));
Paul Bakker5121ce52009-01-03 21:22:43 +0000456
457cleanup:
David Horstmann71159f42023-01-03 12:51:59 +0000458 mbedtls_mpi_free(&GYb);
Paul Bakker5121ce52009-01-03 21:22:43 +0000459
David Horstmann71159f42023-01-03 12:51:59 +0000460 if (ret != 0) {
461 return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_DHM_CALC_SECRET_FAILED, ret);
462 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000463
David Horstmann71159f42023-01-03 12:51:59 +0000464 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000465}
466
467/*
468 * Free the components of a DHM key
469 */
David Horstmann71159f42023-01-03 12:51:59 +0000470void mbedtls_dhm_free(mbedtls_dhm_context *ctx)
Paul Bakker5121ce52009-01-03 21:22:43 +0000471{
David Horstmann71159f42023-01-03 12:51:59 +0000472 if (ctx == NULL) {
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500473 return;
David Horstmann71159f42023-01-03 12:51:59 +0000474 }
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500475
David Horstmann71159f42023-01-03 12:51:59 +0000476 mbedtls_mpi_free(&ctx->pX);
477 mbedtls_mpi_free(&ctx->Vf);
478 mbedtls_mpi_free(&ctx->Vi);
479 mbedtls_mpi_free(&ctx->RP);
480 mbedtls_mpi_free(&ctx->K);
481 mbedtls_mpi_free(&ctx->GY);
482 mbedtls_mpi_free(&ctx->GX);
483 mbedtls_mpi_free(&ctx->X);
484 mbedtls_mpi_free(&ctx->G);
485 mbedtls_mpi_free(&ctx->P);
Manuel Pégourié-Gonnardb72b4ed2013-09-13 13:55:26 +0200486
David Horstmann71159f42023-01-03 12:51:59 +0000487 mbedtls_platform_zeroize(ctx, sizeof(mbedtls_dhm_context));
Paul Bakker5121ce52009-01-03 21:22:43 +0000488}
489
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200490#if defined(MBEDTLS_ASN1_PARSE_C)
Paul Bakker40ce79f2013-09-15 17:43:54 +0200491/*
492 * Parse DHM parameters
493 */
David Horstmann71159f42023-01-03 12:51:59 +0000494int mbedtls_dhm_parse_dhm(mbedtls_dhm_context *dhm, const unsigned char *dhmin,
495 size_t dhminlen)
Paul Bakker40ce79f2013-09-15 17:43:54 +0200496{
Janos Follath24eed8d2019-11-22 13:21:35 +0000497 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker40ce79f2013-09-15 17:43:54 +0200498 size_t len;
499 unsigned char *p, *end;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200500#if defined(MBEDTLS_PEM_PARSE_C)
501 mbedtls_pem_context pem;
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500502#endif /* MBEDTLS_PEM_PARSE_C */
Paul Bakker40ce79f2013-09-15 17:43:54 +0200503
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500504#if defined(MBEDTLS_PEM_PARSE_C)
David Horstmann71159f42023-01-03 12:51:59 +0000505 mbedtls_pem_init(&pem);
Paul Bakker40ce79f2013-09-15 17:43:54 +0200506
Manuel Pégourié-Gonnard43b37cb2015-05-12 11:20:10 +0200507 /* Avoid calling mbedtls_pem_read_buffer() on non-null-terminated string */
David Horstmann71159f42023-01-03 12:51:59 +0000508 if (dhminlen == 0 || dhmin[dhminlen - 1] != '\0') {
Manuel Pégourié-Gonnard43b37cb2015-05-12 11:20:10 +0200509 ret = MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT;
David Horstmann71159f42023-01-03 12:51:59 +0000510 } else {
511 ret = mbedtls_pem_read_buffer(&pem,
512 "-----BEGIN DH PARAMETERS-----",
513 "-----END DH PARAMETERS-----",
514 dhmin, NULL, 0, &dhminlen);
515 }
Paul Bakker40ce79f2013-09-15 17:43:54 +0200516
David Horstmann71159f42023-01-03 12:51:59 +0000517 if (ret == 0) {
Paul Bakker40ce79f2013-09-15 17:43:54 +0200518 /*
519 * Was PEM encoded
520 */
521 dhminlen = pem.buflen;
David Horstmann71159f42023-01-03 12:51:59 +0000522 } else if (ret != MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT) {
Paul Bakker40ce79f2013-09-15 17:43:54 +0200523 goto exit;
David Horstmann71159f42023-01-03 12:51:59 +0000524 }
Paul Bakker40ce79f2013-09-15 17:43:54 +0200525
David Horstmann71159f42023-01-03 12:51:59 +0000526 p = (ret == 0) ? pem.buf : (unsigned char *) dhmin;
Paul Bakker40ce79f2013-09-15 17:43:54 +0200527#else
528 p = (unsigned char *) dhmin;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200529#endif /* MBEDTLS_PEM_PARSE_C */
Paul Bakker40ce79f2013-09-15 17:43:54 +0200530 end = p + dhminlen;
531
532 /*
533 * DHParams ::= SEQUENCE {
Daniel Kahn Gillmor2ed81732015-04-03 13:09:24 -0400534 * prime INTEGER, -- P
535 * generator INTEGER, -- g
536 * privateValueLength INTEGER OPTIONAL
Paul Bakker40ce79f2013-09-15 17:43:54 +0200537 * }
538 */
David Horstmann71159f42023-01-03 12:51:59 +0000539 if ((ret = mbedtls_asn1_get_tag(&p, end, &len,
540 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) {
541 ret = MBEDTLS_ERROR_ADD(MBEDTLS_ERR_DHM_INVALID_FORMAT, ret);
Paul Bakker40ce79f2013-09-15 17:43:54 +0200542 goto exit;
543 }
544
545 end = p + len;
546
David Horstmann71159f42023-01-03 12:51:59 +0000547 if ((ret = mbedtls_asn1_get_mpi(&p, end, &dhm->P)) != 0 ||
548 (ret = mbedtls_asn1_get_mpi(&p, end, &dhm->G)) != 0) {
549 ret = MBEDTLS_ERROR_ADD(MBEDTLS_ERR_DHM_INVALID_FORMAT, ret);
Paul Bakker40ce79f2013-09-15 17:43:54 +0200550 goto exit;
551 }
552
David Horstmann71159f42023-01-03 12:51:59 +0000553 if (p != end) {
Manuel Pégourié-Gonnardde9b3632015-04-17 20:06:31 +0200554 /* This might be the optional privateValueLength.
555 * If so, we can cleanly discard it */
556 mbedtls_mpi rec;
David Horstmann71159f42023-01-03 12:51:59 +0000557 mbedtls_mpi_init(&rec);
558 ret = mbedtls_asn1_get_mpi(&p, end, &rec);
559 mbedtls_mpi_free(&rec);
560 if (ret != 0) {
561 ret = MBEDTLS_ERROR_ADD(MBEDTLS_ERR_DHM_INVALID_FORMAT, ret);
Daniel Kahn Gillmor2ed81732015-04-03 13:09:24 -0400562 goto exit;
563 }
David Horstmann71159f42023-01-03 12:51:59 +0000564 if (p != end) {
565 ret = MBEDTLS_ERROR_ADD(MBEDTLS_ERR_DHM_INVALID_FORMAT,
566 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
Daniel Kahn Gillmor2ed81732015-04-03 13:09:24 -0400567 goto exit;
568 }
Paul Bakker40ce79f2013-09-15 17:43:54 +0200569 }
570
571 ret = 0;
572
573exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200574#if defined(MBEDTLS_PEM_PARSE_C)
David Horstmann71159f42023-01-03 12:51:59 +0000575 mbedtls_pem_free(&pem);
Paul Bakker40ce79f2013-09-15 17:43:54 +0200576#endif
David Horstmann71159f42023-01-03 12:51:59 +0000577 if (ret != 0) {
578 mbedtls_dhm_free(dhm);
579 }
Paul Bakker40ce79f2013-09-15 17:43:54 +0200580
David Horstmann71159f42023-01-03 12:51:59 +0000581 return ret;
Paul Bakker40ce79f2013-09-15 17:43:54 +0200582}
583
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200584#if defined(MBEDTLS_FS_IO)
Paul Bakker40ce79f2013-09-15 17:43:54 +0200585/*
586 * Load all data from a file into a given buffer.
Manuel Pégourié-Gonnard43b37cb2015-05-12 11:20:10 +0200587 *
588 * The file is expected to contain either PEM or DER encoded data.
589 * A terminating null byte is always appended. It is included in the announced
590 * length only if the data looks like it is PEM encoded.
Paul Bakker40ce79f2013-09-15 17:43:54 +0200591 */
David Horstmann71159f42023-01-03 12:51:59 +0000592static int load_file(const char *path, unsigned char **buf, size_t *n)
Paul Bakker40ce79f2013-09-15 17:43:54 +0200593{
594 FILE *f;
595 long size;
596
David Horstmann71159f42023-01-03 12:51:59 +0000597 if ((f = fopen(path, "rb")) == NULL) {
598 return MBEDTLS_ERR_DHM_FILE_IO_ERROR;
599 }
Gilles Peskineda0913b2022-06-30 17:03:40 +0200600 /* The data loaded here is public, so don't bother disabling buffering. */
Paul Bakker40ce79f2013-09-15 17:43:54 +0200601
David Horstmann71159f42023-01-03 12:51:59 +0000602 fseek(f, 0, SEEK_END);
603 if ((size = ftell(f)) == -1) {
604 fclose(f);
605 return MBEDTLS_ERR_DHM_FILE_IO_ERROR;
Paul Bakker40ce79f2013-09-15 17:43:54 +0200606 }
David Horstmann71159f42023-01-03 12:51:59 +0000607 fseek(f, 0, SEEK_SET);
Paul Bakker40ce79f2013-09-15 17:43:54 +0200608
609 *n = (size_t) size;
610
David Horstmann71159f42023-01-03 12:51:59 +0000611 if (*n + 1 == 0 ||
612 (*buf = mbedtls_calloc(1, *n + 1)) == NULL) {
613 fclose(f);
614 return MBEDTLS_ERR_DHM_ALLOC_FAILED;
Paul Bakker40ce79f2013-09-15 17:43:54 +0200615 }
616
David Horstmann71159f42023-01-03 12:51:59 +0000617 if (fread(*buf, 1, *n, f) != *n) {
618 fclose(f);
Andres Amaya Garciabdbca7b2017-06-23 16:23:21 +0100619
David Horstmann71159f42023-01-03 12:51:59 +0000620 mbedtls_platform_zeroize(*buf, *n + 1);
621 mbedtls_free(*buf);
Andres Amaya Garciabdbca7b2017-06-23 16:23:21 +0100622
David Horstmann71159f42023-01-03 12:51:59 +0000623 return MBEDTLS_ERR_DHM_FILE_IO_ERROR;
Paul Bakker40ce79f2013-09-15 17:43:54 +0200624 }
625
David Horstmann71159f42023-01-03 12:51:59 +0000626 fclose(f);
Paul Bakker40ce79f2013-09-15 17:43:54 +0200627
628 (*buf)[*n] = '\0';
629
David Horstmann71159f42023-01-03 12:51:59 +0000630 if (strstr((const char *) *buf, "-----BEGIN ") != NULL) {
Manuel Pégourié-Gonnard43b37cb2015-05-12 11:20:10 +0200631 ++*n;
David Horstmann71159f42023-01-03 12:51:59 +0000632 }
Manuel Pégourié-Gonnard43b37cb2015-05-12 11:20:10 +0200633
David Horstmann71159f42023-01-03 12:51:59 +0000634 return 0;
Paul Bakker40ce79f2013-09-15 17:43:54 +0200635}
636
637/*
638 * Load and parse DHM parameters
639 */
David Horstmann71159f42023-01-03 12:51:59 +0000640int mbedtls_dhm_parse_dhmfile(mbedtls_dhm_context *dhm, const char *path)
Paul Bakker40ce79f2013-09-15 17:43:54 +0200641{
Janos Follath24eed8d2019-11-22 13:21:35 +0000642 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker40ce79f2013-09-15 17:43:54 +0200643 size_t n;
644 unsigned char *buf;
645
David Horstmann71159f42023-01-03 12:51:59 +0000646 if ((ret = load_file(path, &buf, &n)) != 0) {
647 return ret;
648 }
Paul Bakker40ce79f2013-09-15 17:43:54 +0200649
David Horstmann71159f42023-01-03 12:51:59 +0000650 ret = mbedtls_dhm_parse_dhm(dhm, buf, n);
Paul Bakker40ce79f2013-09-15 17:43:54 +0200651
David Horstmann71159f42023-01-03 12:51:59 +0000652 mbedtls_platform_zeroize(buf, n);
653 mbedtls_free(buf);
Paul Bakker40ce79f2013-09-15 17:43:54 +0200654
David Horstmann71159f42023-01-03 12:51:59 +0000655 return ret;
Paul Bakker40ce79f2013-09-15 17:43:54 +0200656}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200657#endif /* MBEDTLS_FS_IO */
658#endif /* MBEDTLS_ASN1_PARSE_C */
nirekh0149762fa2017-12-25 06:46:48 +0000659#endif /* MBEDTLS_DHM_ALT */
Paul Bakker40ce79f2013-09-15 17:43:54 +0200660
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200661#if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +0000662
Hanno Becker8b0f9e62019-05-31 17:28:59 +0100663#if defined(MBEDTLS_PEM_PARSE_C)
Manuel Pégourié-Gonnard53585ee2015-06-25 08:52:25 +0200664static const char mbedtls_test_dhm_params[] =
David Horstmann71159f42023-01-03 12:51:59 +0000665 "-----BEGIN DH PARAMETERS-----\r\n"
666 "MIGHAoGBAJ419DBEOgmQTzo5qXl5fQcN9TN455wkOL7052HzxxRVMyhYmwQcgJvh\r\n"
667 "1sa18fyfR9OiVEMYglOpkqVoGLN7qd5aQNNi5W7/C+VBdHTBJcGZJyyP5B3qcz32\r\n"
668 "9mLJKudlVudV0Qxk5qUJaPZ/xupz0NyoVpviuiBOI1gNi8ovSXWzAgEC\r\n"
669 "-----END DH PARAMETERS-----\r\n";
Hanno Becker8b0f9e62019-05-31 17:28:59 +0100670#else /* MBEDTLS_PEM_PARSE_C */
671static const char mbedtls_test_dhm_params[] = {
David Horstmann71159f42023-01-03 12:51:59 +0000672 0x30, 0x81, 0x87, 0x02, 0x81, 0x81, 0x00, 0x9e, 0x35, 0xf4, 0x30, 0x44,
673 0x3a, 0x09, 0x90, 0x4f, 0x3a, 0x39, 0xa9, 0x79, 0x79, 0x7d, 0x07, 0x0d,
674 0xf5, 0x33, 0x78, 0xe7, 0x9c, 0x24, 0x38, 0xbe, 0xf4, 0xe7, 0x61, 0xf3,
675 0xc7, 0x14, 0x55, 0x33, 0x28, 0x58, 0x9b, 0x04, 0x1c, 0x80, 0x9b, 0xe1,
676 0xd6, 0xc6, 0xb5, 0xf1, 0xfc, 0x9f, 0x47, 0xd3, 0xa2, 0x54, 0x43, 0x18,
677 0x82, 0x53, 0xa9, 0x92, 0xa5, 0x68, 0x18, 0xb3, 0x7b, 0xa9, 0xde, 0x5a,
678 0x40, 0xd3, 0x62, 0xe5, 0x6e, 0xff, 0x0b, 0xe5, 0x41, 0x74, 0x74, 0xc1,
679 0x25, 0xc1, 0x99, 0x27, 0x2c, 0x8f, 0xe4, 0x1d, 0xea, 0x73, 0x3d, 0xf6,
680 0xf6, 0x62, 0xc9, 0x2a, 0xe7, 0x65, 0x56, 0xe7, 0x55, 0xd1, 0x0c, 0x64,
681 0xe6, 0xa5, 0x09, 0x68, 0xf6, 0x7f, 0xc6, 0xea, 0x73, 0xd0, 0xdc, 0xa8,
682 0x56, 0x9b, 0xe2, 0xba, 0x20, 0x4e, 0x23, 0x58, 0x0d, 0x8b, 0xca, 0x2f,
683 0x49, 0x75, 0xb3, 0x02, 0x01, 0x02
684};
Hanno Becker8b0f9e62019-05-31 17:28:59 +0100685#endif /* MBEDTLS_PEM_PARSE_C */
Manuel Pégourié-Gonnard53585ee2015-06-25 08:52:25 +0200686
David Horstmann71159f42023-01-03 12:51:59 +0000687static const size_t mbedtls_test_dhm_params_len = sizeof(mbedtls_test_dhm_params);
Paul Bakker40ce79f2013-09-15 17:43:54 +0200688
Paul Bakker5121ce52009-01-03 21:22:43 +0000689/*
690 * Checkup routine
691 */
David Horstmann71159f42023-01-03 12:51:59 +0000692int mbedtls_dhm_self_test(int verbose)
Paul Bakker5121ce52009-01-03 21:22:43 +0000693{
Janos Follath24eed8d2019-11-22 13:21:35 +0000694 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200695 mbedtls_dhm_context dhm;
Paul Bakker40ce79f2013-09-15 17:43:54 +0200696
David Horstmann71159f42023-01-03 12:51:59 +0000697 mbedtls_dhm_init(&dhm);
Paul Bakker8f870b02014-06-20 13:32:38 +0200698
David Horstmann71159f42023-01-03 12:51:59 +0000699 if (verbose != 0) {
700 mbedtls_printf(" DHM parameter load: ");
701 }
Paul Bakker40ce79f2013-09-15 17:43:54 +0200702
David Horstmann71159f42023-01-03 12:51:59 +0000703 if ((ret = mbedtls_dhm_parse_dhm(&dhm,
704 (const unsigned char *) mbedtls_test_dhm_params,
705 mbedtls_test_dhm_params_len)) != 0) {
706 if (verbose != 0) {
707 mbedtls_printf("failed\n");
708 }
Paul Bakker40ce79f2013-09-15 17:43:54 +0200709
Manuel Pégourié-Gonnardb196fc22014-07-09 16:53:29 +0200710 ret = 1;
Paul Bakker8f870b02014-06-20 13:32:38 +0200711 goto exit;
Paul Bakker40ce79f2013-09-15 17:43:54 +0200712 }
713
David Horstmann71159f42023-01-03 12:51:59 +0000714 if (verbose != 0) {
715 mbedtls_printf("passed\n\n");
716 }
Paul Bakker40ce79f2013-09-15 17:43:54 +0200717
Paul Bakker8f870b02014-06-20 13:32:38 +0200718exit:
David Horstmann71159f42023-01-03 12:51:59 +0000719 mbedtls_dhm_free(&dhm);
Paul Bakker40ce79f2013-09-15 17:43:54 +0200720
David Horstmann71159f42023-01-03 12:51:59 +0000721 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +0000722}
723
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200724#endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +0000725
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200726#endif /* MBEDTLS_DHM_C */