blob: 3c65bc8076559788218edde0898a2fbdd9c4350a [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
Dave Rodgman16799db2023-11-02 19:47:20 +00005 * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
Paul Bakker5121ce52009-01-03 21:22:43 +00006 */
7/*
Simon Butcherbdae02c2016-01-20 00:44:42 +00008 * The following sources were referenced in the design of this implementation
9 * of the Diffie-Hellman-Merkle algorithm:
Paul Bakker5121ce52009-01-03 21:22:43 +000010 *
Simon Butcherbdae02c2016-01-20 00:44:42 +000011 * [1] Handbook of Applied Cryptography - 1997, Chapter 12
12 * Menezes, van Oorschot and Vanstone
13 *
Paul Bakker5121ce52009-01-03 21:22:43 +000014 */
15
Gilles Peskinedb09ef62020-06-03 01:43:33 +020016#include "common.h"
Paul Bakker5121ce52009-01-03 21:22:43 +000017
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020018#if defined(MBEDTLS_DHM_C)
Paul Bakker5121ce52009-01-03 21:22:43 +000019
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000020#include "mbedtls/dhm.h"
Manuel Pégourié-Gonnardc2d210e2025-07-10 21:48:41 +020021#include "bignum_internal.h"
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -050022#include "mbedtls/platform_util.h"
Janos Follath24eed8d2019-11-22 13:21:35 +000023#include "mbedtls/error.h"
Paul Bakker5121ce52009-01-03 21:22:43 +000024
Rich Evans00ab4702015-02-06 13:43:58 +000025#include <string.h>
26
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020027#if defined(MBEDTLS_PEM_PARSE_C)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000028#include "mbedtls/pem.h"
Paul Bakker40ce79f2013-09-15 17:43:54 +020029#endif
30
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020031#if defined(MBEDTLS_ASN1_PARSE_C)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000032#include "mbedtls/asn1.h"
Paul Bakker40ce79f2013-09-15 17:43:54 +020033#endif
34
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000035#include "mbedtls/platform.h"
Paul Bakker40ce79f2013-09-15 17:43:54 +020036
Reuven Levin1f35ca92017-12-07 10:09:32 +000037#if !defined(MBEDTLS_DHM_ALT)
Paul Bakker34617722014-06-13 17:20:13 +020038
Paul Bakker5121ce52009-01-03 21:22:43 +000039/*
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020040 * helper to validate the mbedtls_mpi size and import it
Paul Bakker5121ce52009-01-03 21:22:43 +000041 */
Gilles Peskine449bd832023-01-11 14:50:10 +010042static int dhm_read_bignum(mbedtls_mpi *X,
43 unsigned char **p,
44 const unsigned char *end)
Paul Bakker5121ce52009-01-03 21:22:43 +000045{
46 int ret, n;
47
Gilles Peskine449bd832023-01-11 14:50:10 +010048 if (end - *p < 2) {
49 return MBEDTLS_ERR_DHM_BAD_INPUT_DATA;
50 }
Paul Bakker5121ce52009-01-03 21:22:43 +000051
Dave Rodgmana3d0f612023-11-03 23:34:02 +000052 n = MBEDTLS_GET_UINT16_BE(*p, 0);
Paul Bakker5121ce52009-01-03 21:22:43 +000053 (*p) += 2;
54
Dave Rodgmane4a6f5a2023-11-04 12:20:09 +000055 if ((size_t) (end - *p) < (size_t) n) {
Gilles Peskine449bd832023-01-11 14:50:10 +010056 return MBEDTLS_ERR_DHM_BAD_INPUT_DATA;
57 }
Paul Bakker5121ce52009-01-03 21:22:43 +000058
Gilles Peskine449bd832023-01-11 14:50:10 +010059 if ((ret = mbedtls_mpi_read_binary(X, *p, n)) != 0) {
60 return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_DHM_READ_PARAMS_FAILED, ret);
61 }
Paul Bakker5121ce52009-01-03 21:22:43 +000062
63 (*p) += n;
64
Gilles Peskine449bd832023-01-11 14:50:10 +010065 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +000066}
67
68/*
Paul Bakkeraec37cb2012-04-26 18:59:59 +000069 * Verify sanity of parameter with regards to P
Paul Bakker345a6fe2011-02-28 21:20:02 +000070 *
Paul Bakkeraec37cb2012-04-26 18:59:59 +000071 * Parameter should be: 2 <= public_param <= P - 2
Paul Bakker345a6fe2011-02-28 21:20:02 +000072 *
Janos Follathaa325d72017-09-20 15:33:24 +010073 * This means that we need to return an error if
Janos Follath1ad1c6d2017-09-21 09:02:11 +010074 * public_param < 2 or public_param > P-2
Janos Follathaa325d72017-09-20 15:33:24 +010075 *
Paul Bakker345a6fe2011-02-28 21:20:02 +000076 * For more information on the attack, see:
77 * http://www.cl.cam.ac.uk/~rja14/Papers/psandqs.pdf
78 * http://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2005-2643
Paul Bakkerc47840e2011-02-20 16:37:30 +000079 */
Gilles Peskine449bd832023-01-11 14:50:10 +010080static int dhm_check_range(const mbedtls_mpi *param, const mbedtls_mpi *P)
Paul Bakkerc47840e2011-02-20 16:37:30 +000081{
Gilles Peskine8e38acc2021-03-31 22:56:43 +020082 mbedtls_mpi U;
Janos Follathaa325d72017-09-20 15:33:24 +010083 int ret = 0;
Paul Bakkerc47840e2011-02-20 16:37:30 +000084
Gilles Peskine449bd832023-01-11 14:50:10 +010085 mbedtls_mpi_init(&U);
Paul Bakker3d8fb632014-04-17 12:42:41 +020086
Gilles Peskine449bd832023-01-11 14:50:10 +010087 MBEDTLS_MPI_CHK(mbedtls_mpi_sub_int(&U, P, 2));
Paul Bakkerc47840e2011-02-20 16:37:30 +000088
Gilles Peskine449bd832023-01-11 14:50:10 +010089 if (mbedtls_mpi_cmp_int(param, 2) < 0 ||
90 mbedtls_mpi_cmp_mpi(param, &U) > 0) {
Janos Follathaa325d72017-09-20 15:33:24 +010091 ret = MBEDTLS_ERR_DHM_BAD_INPUT_DATA;
Paul Bakkerc47840e2011-02-20 16:37:30 +000092 }
93
Paul Bakker3d8fb632014-04-17 12:42:41 +020094cleanup:
Gilles Peskine449bd832023-01-11 14:50:10 +010095 mbedtls_mpi_free(&U);
96 return ret;
Paul Bakkerc47840e2011-02-20 16:37:30 +000097}
98
Gilles Peskine449bd832023-01-11 14:50:10 +010099void mbedtls_dhm_init(mbedtls_dhm_context *ctx)
Paul Bakker8f870b02014-06-20 13:32:38 +0200100{
Gilles Peskine449bd832023-01-11 14:50:10 +0100101 memset(ctx, 0, sizeof(mbedtls_dhm_context));
Paul Bakker8f870b02014-06-20 13:32:38 +0200102}
103
Gilles Peskine449bd832023-01-11 14:50:10 +0100104size_t mbedtls_dhm_get_bitlen(const mbedtls_dhm_context *ctx)
Gilles Peskine487bbf62021-05-27 22:17:07 +0200105{
Gilles Peskine449bd832023-01-11 14:50:10 +0100106 return mbedtls_mpi_bitlen(&ctx->P);
Gilles Peskine487bbf62021-05-27 22:17:07 +0200107}
108
Gilles Peskine449bd832023-01-11 14:50:10 +0100109size_t mbedtls_dhm_get_len(const mbedtls_dhm_context *ctx)
Gilles Peskine487bbf62021-05-27 22:17:07 +0200110{
Gilles Peskine449bd832023-01-11 14:50:10 +0100111 return mbedtls_mpi_size(&ctx->P);
Gilles Peskine487bbf62021-05-27 22:17:07 +0200112}
113
Gilles Peskine449bd832023-01-11 14:50:10 +0100114int mbedtls_dhm_get_value(const mbedtls_dhm_context *ctx,
115 mbedtls_dhm_parameter param,
116 mbedtls_mpi *dest)
Gilles Peskine71acc6e2021-05-27 22:50:53 +0200117{
118 const mbedtls_mpi *src = NULL;
Gilles Peskine449bd832023-01-11 14:50:10 +0100119 switch (param) {
Gilles Peskine71acc6e2021-05-27 22:50:53 +0200120 case MBEDTLS_DHM_PARAM_P:
121 src = &ctx->P;
122 break;
123 case MBEDTLS_DHM_PARAM_G:
124 src = &ctx->G;
125 break;
126 case MBEDTLS_DHM_PARAM_X:
127 src = &ctx->X;
128 break;
129 case MBEDTLS_DHM_PARAM_GX:
130 src = &ctx->GX;
131 break;
132 case MBEDTLS_DHM_PARAM_GY:
133 src = &ctx->GY;
134 break;
135 case MBEDTLS_DHM_PARAM_K:
136 src = &ctx->K;
137 break;
138 default:
Gilles Peskine449bd832023-01-11 14:50:10 +0100139 return MBEDTLS_ERR_DHM_BAD_INPUT_DATA;
Gilles Peskine71acc6e2021-05-27 22:50:53 +0200140 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100141 return mbedtls_mpi_copy(dest, src);
Gilles Peskine71acc6e2021-05-27 22:50:53 +0200142}
143
Paul Bakkerc47840e2011-02-20 16:37:30 +0000144/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000145 * Parse the ServerKeyExchange parameters
146 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100147int mbedtls_dhm_read_params(mbedtls_dhm_context *ctx,
148 unsigned char **p,
149 const unsigned char *end)
Paul Bakker5121ce52009-01-03 21:22:43 +0000150{
Janos Follath24eed8d2019-11-22 13:21:35 +0000151 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker5121ce52009-01-03 21:22:43 +0000152
Gilles Peskine449bd832023-01-11 14:50:10 +0100153 if ((ret = dhm_read_bignum(&ctx->P, p, end)) != 0 ||
154 (ret = dhm_read_bignum(&ctx->G, p, end)) != 0 ||
155 (ret = dhm_read_bignum(&ctx->GY, p, end)) != 0) {
156 return ret;
157 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000158
Gilles Peskine449bd832023-01-11 14:50:10 +0100159 if ((ret = dhm_check_range(&ctx->GY, &ctx->P)) != 0) {
160 return ret;
161 }
Paul Bakker345a6fe2011-02-28 21:20:02 +0000162
Gilles Peskine449bd832023-01-11 14:50:10 +0100163 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000164}
165
Gilles Peskine17f1a262021-03-31 22:48:14 +0200166/*
Gilles Peskineda7ee012021-03-31 23:04:50 +0200167 * Pick a random R in the range [2, M-2] for blinding or key generation.
Gilles Peskine17f1a262021-03-31 22:48:14 +0200168 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100169static int dhm_random_below(mbedtls_mpi *R, const mbedtls_mpi *M,
170 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng)
Gilles Peskine17f1a262021-03-31 22:48:14 +0200171{
Gilles Peskineda7ee012021-03-31 23:04:50 +0200172 int ret;
Gilles Peskine17f1a262021-03-31 22:48:14 +0200173
Gilles Peskine449bd832023-01-11 14:50:10 +0100174 MBEDTLS_MPI_CHK(mbedtls_mpi_random(R, 3, M, f_rng, p_rng));
175 MBEDTLS_MPI_CHK(mbedtls_mpi_sub_int(R, R, 1));
Gilles Peskine17f1a262021-03-31 22:48:14 +0200176
177cleanup:
Gilles Peskine449bd832023-01-11 14:50:10 +0100178 return ret;
Gilles Peskine17f1a262021-03-31 22:48:14 +0200179}
180
Gilles Peskine449bd832023-01-11 14:50:10 +0100181static int dhm_make_common(mbedtls_dhm_context *ctx, int x_size,
182 int (*f_rng)(void *, unsigned char *, size_t),
183 void *p_rng)
Paul Bakker5121ce52009-01-03 21:22:43 +0000184{
Gilles Peskine17f1a262021-03-31 22:48:14 +0200185 int ret = 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000186
Gilles Peskine449bd832023-01-11 14:50:10 +0100187 if (mbedtls_mpi_cmp_int(&ctx->P, 0) == 0) {
188 return MBEDTLS_ERR_DHM_BAD_INPUT_DATA;
Paul Bakkeraec37cb2012-04-26 18:59:59 +0000189 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100190 if (x_size < 0) {
191 return MBEDTLS_ERR_DHM_BAD_INPUT_DATA;
192 }
193
194 if ((unsigned) x_size < mbedtls_mpi_size(&ctx->P)) {
195 MBEDTLS_MPI_CHK(mbedtls_mpi_fill_random(&ctx->X, x_size, f_rng, p_rng));
196 } else {
Gilles Peskine17f1a262021-03-31 22:48:14 +0200197 /* Generate X as large as possible ( <= P - 2 ) */
Gilles Peskine449bd832023-01-11 14:50:10 +0100198 ret = dhm_random_below(&ctx->X, &ctx->P, f_rng, p_rng);
199 if (ret == MBEDTLS_ERR_MPI_NOT_ACCEPTABLE) {
200 return MBEDTLS_ERR_DHM_MAKE_PARAMS_FAILED;
201 }
202 if (ret != 0) {
203 return ret;
204 }
Gilles Peskine17f1a262021-03-31 22:48:14 +0200205 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000206
Paul Bakkerff7fe672010-07-18 09:45:05 +0000207 /*
208 * Calculate GX = G^X mod P
209 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100210 MBEDTLS_MPI_CHK(mbedtls_mpi_exp_mod(&ctx->GX, &ctx->G, &ctx->X,
211 &ctx->P, &ctx->RP));
Paul Bakker5121ce52009-01-03 21:22:43 +0000212
Gilles Peskine449bd832023-01-11 14:50:10 +0100213 if ((ret = dhm_check_range(&ctx->GX, &ctx->P)) != 0) {
214 return ret;
215 }
Paul Bakkerc47840e2011-02-20 16:37:30 +0000216
Gilles Peskinecb660f22021-03-31 22:35:13 +0200217cleanup:
Gilles Peskine449bd832023-01-11 14:50:10 +0100218 return ret;
Gilles Peskinecb660f22021-03-31 22:35:13 +0200219}
220
221/*
222 * Setup and write the ServerKeyExchange parameters
223 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100224int mbedtls_dhm_make_params(mbedtls_dhm_context *ctx, int x_size,
225 unsigned char *output, size_t *olen,
226 int (*f_rng)(void *, unsigned char *, size_t),
227 void *p_rng)
Gilles Peskinecb660f22021-03-31 22:35:13 +0200228{
229 int ret;
230 size_t n1, n2, n3;
231 unsigned char *p;
Gilles Peskinecb660f22021-03-31 22:35:13 +0200232
Gilles Peskine449bd832023-01-11 14:50:10 +0100233 ret = dhm_make_common(ctx, x_size, f_rng, p_rng);
234 if (ret != 0) {
Gilles Peskinecb660f22021-03-31 22:35:13 +0200235 goto cleanup;
Gilles Peskine449bd832023-01-11 14:50:10 +0100236 }
Gilles Peskinecb660f22021-03-31 22:35:13 +0200237
Paul Bakker5121ce52009-01-03 21:22:43 +0000238 /*
Gilles Peskine03299dc2021-04-13 22:10:24 +0200239 * Export P, G, GX. RFC 5246 §4.4 states that "leading zero octets are
240 * not required". We omit leading zeros for compactness.
Paul Bakker5121ce52009-01-03 21:22:43 +0000241 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100242#define DHM_MPI_EXPORT(X, n) \
Hanno Beckere71ad122017-09-28 10:32:25 +0100243 do { \
Gilles Peskine449bd832023-01-11 14:50:10 +0100244 MBEDTLS_MPI_CHK(mbedtls_mpi_write_binary((X), \
245 p + 2, \
246 (n))); \
247 *p++ = MBEDTLS_BYTE_1(n); \
248 *p++ = MBEDTLS_BYTE_0(n); \
249 p += (n); \
250 } while (0)
Paul Bakker5121ce52009-01-03 21:22:43 +0000251
Gilles Peskine449bd832023-01-11 14:50:10 +0100252 n1 = mbedtls_mpi_size(&ctx->P);
253 n2 = mbedtls_mpi_size(&ctx->G);
254 n3 = mbedtls_mpi_size(&ctx->GX);
Paul Bakker5121ce52009-01-03 21:22:43 +0000255
256 p = output;
Gilles Peskine449bd832023-01-11 14:50:10 +0100257 DHM_MPI_EXPORT(&ctx->P, n1);
258 DHM_MPI_EXPORT(&ctx->G, n2);
259 DHM_MPI_EXPORT(&ctx->GX, n3);
Paul Bakker5121ce52009-01-03 21:22:43 +0000260
Dave Rodgmane4a6f5a2023-11-04 12:20:09 +0000261 *olen = (size_t) (p - output);
Paul Bakker5121ce52009-01-03 21:22:43 +0000262
Paul Bakker5121ce52009-01-03 21:22:43 +0000263cleanup:
Gilles Peskine449bd832023-01-11 14:50:10 +0100264 if (ret != 0 && ret > -128) {
265 ret = MBEDTLS_ERROR_ADD(MBEDTLS_ERR_DHM_MAKE_PARAMS_FAILED, ret);
266 }
267 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +0000268}
269
270/*
Hanno Becker8880e752017-10-04 13:15:08 +0100271 * Set prime modulus and generator
272 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100273int mbedtls_dhm_set_group(mbedtls_dhm_context *ctx,
274 const mbedtls_mpi *P,
275 const mbedtls_mpi *G)
Hanno Becker8880e752017-10-04 13:15:08 +0100276{
Janos Follath24eed8d2019-11-22 13:21:35 +0000277 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Hanno Becker8880e752017-10-04 13:15:08 +0100278
Gilles Peskine449bd832023-01-11 14:50:10 +0100279 if ((ret = mbedtls_mpi_copy(&ctx->P, P)) != 0 ||
280 (ret = mbedtls_mpi_copy(&ctx->G, G)) != 0) {
281 return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_DHM_SET_GROUP_FAILED, ret);
Hanno Becker8880e752017-10-04 13:15:08 +0100282 }
283
Gilles Peskine449bd832023-01-11 14:50:10 +0100284 return 0;
Hanno Becker8880e752017-10-04 13:15:08 +0100285}
286
287/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000288 * Import the peer's public value G^Y
289 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100290int mbedtls_dhm_read_public(mbedtls_dhm_context *ctx,
291 const unsigned char *input, size_t ilen)
Paul Bakker5121ce52009-01-03 21:22:43 +0000292{
Janos Follath24eed8d2019-11-22 13:21:35 +0000293 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker5121ce52009-01-03 21:22:43 +0000294
Gilles Peskine449bd832023-01-11 14:50:10 +0100295 if (ilen < 1 || ilen > mbedtls_dhm_get_len(ctx)) {
296 return MBEDTLS_ERR_DHM_BAD_INPUT_DATA;
297 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000298
Gilles Peskine449bd832023-01-11 14:50:10 +0100299 if ((ret = mbedtls_mpi_read_binary(&ctx->GY, input, ilen)) != 0) {
300 return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_DHM_READ_PUBLIC_FAILED, ret);
301 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000302
Gilles Peskine449bd832023-01-11 14:50:10 +0100303 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000304}
305
306/*
307 * Create own private value X and export G^X
308 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100309int mbedtls_dhm_make_public(mbedtls_dhm_context *ctx, int x_size,
310 unsigned char *output, size_t olen,
311 int (*f_rng)(void *, unsigned char *, size_t),
312 void *p_rng)
Paul Bakker5121ce52009-01-03 21:22:43 +0000313{
Gilles Peskinecb660f22021-03-31 22:35:13 +0200314 int ret;
Paul Bakker5121ce52009-01-03 21:22:43 +0000315
Gilles Peskine449bd832023-01-11 14:50:10 +0100316 if (olen < 1 || olen > mbedtls_dhm_get_len(ctx)) {
317 return MBEDTLS_ERR_DHM_BAD_INPUT_DATA;
318 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000319
Gilles Peskine449bd832023-01-11 14:50:10 +0100320 ret = dhm_make_common(ctx, x_size, f_rng, p_rng);
321 if (ret == MBEDTLS_ERR_DHM_MAKE_PARAMS_FAILED) {
322 return MBEDTLS_ERR_DHM_MAKE_PUBLIC_FAILED;
323 }
324 if (ret != 0) {
Gilles Peskinecb660f22021-03-31 22:35:13 +0200325 goto cleanup;
Gilles Peskine449bd832023-01-11 14:50:10 +0100326 }
Paul Bakkerc47840e2011-02-20 16:37:30 +0000327
Gilles Peskine449bd832023-01-11 14:50:10 +0100328 MBEDTLS_MPI_CHK(mbedtls_mpi_write_binary(&ctx->GX, output, olen));
Paul Bakker5121ce52009-01-03 21:22:43 +0000329
330cleanup:
Gilles Peskine449bd832023-01-11 14:50:10 +0100331 if (ret != 0 && ret > -128) {
332 ret = MBEDTLS_ERROR_ADD(MBEDTLS_ERR_DHM_MAKE_PUBLIC_FAILED, ret);
333 }
334 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +0000335}
336
Manuel Pégourié-Gonnard9f58c4b2020-06-25 12:34:58 +0200337
338/*
Manuel Pégourié-Gonnard143b5022013-09-04 16:29:59 +0200339 * Use the blinding method and optimisation suggested in section 10 of:
340 * KOCHER, Paul C. Timing attacks on implementations of Diffie-Hellman, RSA,
Manuel Pégourié-Gonnard998930a2015-04-03 13:48:06 +0200341 * DSS, and other systems. In : Advances in Cryptology-CRYPTO'96. Springer
Manuel Pégourié-Gonnard143b5022013-09-04 16:29:59 +0200342 * Berlin Heidelberg, 1996. p. 104-113.
343 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100344static int dhm_update_blinding(mbedtls_dhm_context *ctx,
345 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng)
Manuel Pégourié-Gonnard143b5022013-09-04 16:29:59 +0200346{
Manuel Pégourié-Gonnard9f58c4b2020-06-25 12:34:58 +0200347 int ret;
Manuel Pégourié-Gonnardaf721672020-06-25 12:47:22 +0200348 mbedtls_mpi R;
349
Gilles Peskine449bd832023-01-11 14:50:10 +0100350 mbedtls_mpi_init(&R);
Manuel Pégourié-Gonnard143b5022013-09-04 16:29:59 +0200351
352 /*
Manuel Pégourié-Gonnard15d5de12013-09-17 11:34:11 +0200353 * Don't use any blinding the first time a particular X is used,
354 * but remember it to use blinding next time.
Manuel Pégourié-Gonnard143b5022013-09-04 16:29:59 +0200355 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100356 if (mbedtls_mpi_cmp_mpi(&ctx->X, &ctx->pX) != 0) {
357 MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&ctx->pX, &ctx->X));
358 MBEDTLS_MPI_CHK(mbedtls_mpi_lset(&ctx->Vi, 1));
359 MBEDTLS_MPI_CHK(mbedtls_mpi_lset(&ctx->Vf, 1));
Manuel Pégourié-Gonnarded8a02b2013-09-04 16:39:03 +0200360
Gilles Peskine449bd832023-01-11 14:50:10 +0100361 return 0;
Manuel Pégourié-Gonnard143b5022013-09-04 16:29:59 +0200362 }
363
364 /*
Manuel Pégourié-Gonnard15d5de12013-09-17 11:34:11 +0200365 * Ok, we need blinding. Can we re-use existing values?
366 * If yes, just update them by squaring them.
Manuel Pégourié-Gonnard143b5022013-09-04 16:29:59 +0200367 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100368 if (mbedtls_mpi_cmp_int(&ctx->Vi, 1) != 0) {
369 MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(&ctx->Vi, &ctx->Vi, &ctx->Vi));
370 MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(&ctx->Vi, &ctx->Vi, &ctx->P));
Manuel Pégourié-Gonnard15d5de12013-09-17 11:34:11 +0200371
Gilles Peskine449bd832023-01-11 14:50:10 +0100372 MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(&ctx->Vf, &ctx->Vf, &ctx->Vf));
373 MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(&ctx->Vf, &ctx->Vf, &ctx->P));
Manuel Pégourié-Gonnard15d5de12013-09-17 11:34:11 +0200374
Gilles Peskine449bd832023-01-11 14:50:10 +0100375 return 0;
Manuel Pégourié-Gonnard15d5de12013-09-17 11:34:11 +0200376 }
377
378 /*
379 * We need to generate blinding values from scratch
380 */
381
Gilles Peskine7b2b66e2021-03-31 22:50:57 +0200382 /* Vi = random( 2, P-2 ) */
Gilles Peskine449bd832023-01-11 14:50:10 +0100383 MBEDTLS_MPI_CHK(dhm_random_below(&ctx->Vi, &ctx->P, f_rng, p_rng));
Manuel Pégourié-Gonnard15d5de12013-09-17 11:34:11 +0200384
Manuel Pégourié-Gonnardc2d210e2025-07-10 21:48:41 +0200385 /* Vf = Vi^-X mod P */
386 MBEDTLS_MPI_CHK(mbedtls_mpi_gcd_modinv_odd(NULL, &ctx->Vf, &ctx->Vi, &ctx->P));
Gilles Peskine449bd832023-01-11 14:50:10 +0100387 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 +0200388
Manuel Pégourié-Gonnard143b5022013-09-04 16:29:59 +0200389cleanup:
Gilles Peskine449bd832023-01-11 14:50:10 +0100390 mbedtls_mpi_free(&R);
Manuel Pégourié-Gonnardaf721672020-06-25 12:47:22 +0200391
Gilles Peskine449bd832023-01-11 14:50:10 +0100392 return ret;
Manuel Pégourié-Gonnard143b5022013-09-04 16:29:59 +0200393}
394
395/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000396 * Derive and export the shared secret (G^Y)^X mod P
397 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100398int mbedtls_dhm_calc_secret(mbedtls_dhm_context *ctx,
399 unsigned char *output, size_t output_size, size_t *olen,
400 int (*f_rng)(void *, unsigned char *, size_t),
401 void *p_rng)
Paul Bakker5121ce52009-01-03 21:22:43 +0000402{
Janos Follath24eed8d2019-11-22 13:21:35 +0000403 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200404 mbedtls_mpi GYb;
Manuel Pégourié-Gonnard2d627642013-09-04 14:22:07 +0200405
Gilles Peskine449bd832023-01-11 14:50:10 +0100406 if (f_rng == NULL) {
407 return MBEDTLS_ERR_DHM_BAD_INPUT_DATA;
408 }
Manuel Pégourié-Gonnard1a877222021-06-15 11:29:26 +0200409
Gilles Peskine449bd832023-01-11 14:50:10 +0100410 if (output_size < mbedtls_dhm_get_len(ctx)) {
411 return MBEDTLS_ERR_DHM_BAD_INPUT_DATA;
412 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000413
Gilles Peskine449bd832023-01-11 14:50:10 +0100414 if ((ret = dhm_check_range(&ctx->GY, &ctx->P)) != 0) {
415 return ret;
416 }
Paul Bakkerc47840e2011-02-20 16:37:30 +0000417
Gilles Peskine449bd832023-01-11 14:50:10 +0100418 mbedtls_mpi_init(&GYb);
Manuel Pégourié-Gonnard143b5022013-09-04 16:29:59 +0200419
420 /* Blind peer's value */
Gilles Peskine449bd832023-01-11 14:50:10 +0100421 MBEDTLS_MPI_CHK(dhm_update_blinding(ctx, f_rng, p_rng));
422 MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(&GYb, &ctx->GY, &ctx->Vi));
423 MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(&GYb, &GYb, &ctx->P));
Manuel Pégourié-Gonnard143b5022013-09-04 16:29:59 +0200424
425 /* Do modular exponentiation */
Gilles Peskine449bd832023-01-11 14:50:10 +0100426 MBEDTLS_MPI_CHK(mbedtls_mpi_exp_mod(&ctx->K, &GYb, &ctx->X,
427 &ctx->P, &ctx->RP));
Manuel Pégourié-Gonnard143b5022013-09-04 16:29:59 +0200428
429 /* Unblind secret value */
Gilles Peskine449bd832023-01-11 14:50:10 +0100430 MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(&ctx->K, &ctx->K, &ctx->Vf));
431 MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(&ctx->K, &ctx->K, &ctx->P));
Manuel Pégourié-Gonnard143b5022013-09-04 16:29:59 +0200432
Gilles Peskine03299dc2021-04-13 22:10:24 +0200433 /* Output the secret without any leading zero byte. This is mandatory
434 * for TLS per RFC 5246 §8.1.2. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100435 *olen = mbedtls_mpi_size(&ctx->K);
436 MBEDTLS_MPI_CHK(mbedtls_mpi_write_binary(&ctx->K, output, *olen));
Paul Bakker5121ce52009-01-03 21:22:43 +0000437
438cleanup:
Gilles Peskine449bd832023-01-11 14:50:10 +0100439 mbedtls_mpi_free(&GYb);
Paul Bakker5121ce52009-01-03 21:22:43 +0000440
Gilles Peskine449bd832023-01-11 14:50:10 +0100441 if (ret != 0) {
442 return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_DHM_CALC_SECRET_FAILED, ret);
443 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000444
Gilles Peskine449bd832023-01-11 14:50:10 +0100445 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000446}
447
448/*
449 * Free the components of a DHM key
450 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100451void mbedtls_dhm_free(mbedtls_dhm_context *ctx)
Paul Bakker5121ce52009-01-03 21:22:43 +0000452{
Gilles Peskine449bd832023-01-11 14:50:10 +0100453 if (ctx == NULL) {
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500454 return;
Gilles Peskine449bd832023-01-11 14:50:10 +0100455 }
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500456
Gilles Peskine449bd832023-01-11 14:50:10 +0100457 mbedtls_mpi_free(&ctx->pX);
458 mbedtls_mpi_free(&ctx->Vf);
459 mbedtls_mpi_free(&ctx->Vi);
460 mbedtls_mpi_free(&ctx->RP);
461 mbedtls_mpi_free(&ctx->K);
462 mbedtls_mpi_free(&ctx->GY);
463 mbedtls_mpi_free(&ctx->GX);
464 mbedtls_mpi_free(&ctx->X);
465 mbedtls_mpi_free(&ctx->G);
466 mbedtls_mpi_free(&ctx->P);
Manuel Pégourié-Gonnardb72b4ed2013-09-13 13:55:26 +0200467
Gilles Peskine449bd832023-01-11 14:50:10 +0100468 mbedtls_platform_zeroize(ctx, sizeof(mbedtls_dhm_context));
Paul Bakker5121ce52009-01-03 21:22:43 +0000469}
470
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200471#if defined(MBEDTLS_ASN1_PARSE_C)
Paul Bakker40ce79f2013-09-15 17:43:54 +0200472/*
473 * Parse DHM parameters
474 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100475int mbedtls_dhm_parse_dhm(mbedtls_dhm_context *dhm, const unsigned char *dhmin,
476 size_t dhminlen)
Paul Bakker40ce79f2013-09-15 17:43:54 +0200477{
Janos Follath24eed8d2019-11-22 13:21:35 +0000478 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker40ce79f2013-09-15 17:43:54 +0200479 size_t len;
480 unsigned char *p, *end;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200481#if defined(MBEDTLS_PEM_PARSE_C)
482 mbedtls_pem_context pem;
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500483#endif /* MBEDTLS_PEM_PARSE_C */
Paul Bakker40ce79f2013-09-15 17:43:54 +0200484
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500485#if defined(MBEDTLS_PEM_PARSE_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100486 mbedtls_pem_init(&pem);
Paul Bakker40ce79f2013-09-15 17:43:54 +0200487
Manuel Pégourié-Gonnard43b37cb2015-05-12 11:20:10 +0200488 /* Avoid calling mbedtls_pem_read_buffer() on non-null-terminated string */
Gilles Peskine449bd832023-01-11 14:50:10 +0100489 if (dhminlen == 0 || dhmin[dhminlen - 1] != '\0') {
Manuel Pégourié-Gonnard43b37cb2015-05-12 11:20:10 +0200490 ret = MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT;
Gilles Peskine449bd832023-01-11 14:50:10 +0100491 } else {
492 ret = mbedtls_pem_read_buffer(&pem,
493 "-----BEGIN DH PARAMETERS-----",
494 "-----END DH PARAMETERS-----",
495 dhmin, NULL, 0, &dhminlen);
496 }
Paul Bakker40ce79f2013-09-15 17:43:54 +0200497
Gilles Peskine449bd832023-01-11 14:50:10 +0100498 if (ret == 0) {
Paul Bakker40ce79f2013-09-15 17:43:54 +0200499 /*
500 * Was PEM encoded
501 */
502 dhminlen = pem.buflen;
Gilles Peskine449bd832023-01-11 14:50:10 +0100503 } else if (ret != MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT) {
Paul Bakker40ce79f2013-09-15 17:43:54 +0200504 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100505 }
Paul Bakker40ce79f2013-09-15 17:43:54 +0200506
Gilles Peskine449bd832023-01-11 14:50:10 +0100507 p = (ret == 0) ? pem.buf : (unsigned char *) dhmin;
Paul Bakker40ce79f2013-09-15 17:43:54 +0200508#else
509 p = (unsigned char *) dhmin;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200510#endif /* MBEDTLS_PEM_PARSE_C */
Paul Bakker40ce79f2013-09-15 17:43:54 +0200511 end = p + dhminlen;
512
513 /*
514 * DHParams ::= SEQUENCE {
Daniel Kahn Gillmor2ed81732015-04-03 13:09:24 -0400515 * prime INTEGER, -- P
516 * generator INTEGER, -- g
517 * privateValueLength INTEGER OPTIONAL
Paul Bakker40ce79f2013-09-15 17:43:54 +0200518 * }
519 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100520 if ((ret = mbedtls_asn1_get_tag(&p, end, &len,
521 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) {
522 ret = MBEDTLS_ERROR_ADD(MBEDTLS_ERR_DHM_INVALID_FORMAT, ret);
Paul Bakker40ce79f2013-09-15 17:43:54 +0200523 goto exit;
524 }
525
526 end = p + len;
527
Gilles Peskine449bd832023-01-11 14:50:10 +0100528 if ((ret = mbedtls_asn1_get_mpi(&p, end, &dhm->P)) != 0 ||
529 (ret = mbedtls_asn1_get_mpi(&p, end, &dhm->G)) != 0) {
530 ret = MBEDTLS_ERROR_ADD(MBEDTLS_ERR_DHM_INVALID_FORMAT, ret);
Paul Bakker40ce79f2013-09-15 17:43:54 +0200531 goto exit;
532 }
533
Gilles Peskine449bd832023-01-11 14:50:10 +0100534 if (p != end) {
Manuel Pégourié-Gonnardde9b3632015-04-17 20:06:31 +0200535 /* This might be the optional privateValueLength.
536 * If so, we can cleanly discard it */
537 mbedtls_mpi rec;
Gilles Peskine449bd832023-01-11 14:50:10 +0100538 mbedtls_mpi_init(&rec);
539 ret = mbedtls_asn1_get_mpi(&p, end, &rec);
540 mbedtls_mpi_free(&rec);
541 if (ret != 0) {
542 ret = MBEDTLS_ERROR_ADD(MBEDTLS_ERR_DHM_INVALID_FORMAT, ret);
Daniel Kahn Gillmor2ed81732015-04-03 13:09:24 -0400543 goto exit;
544 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100545 if (p != end) {
546 ret = MBEDTLS_ERROR_ADD(MBEDTLS_ERR_DHM_INVALID_FORMAT,
547 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
Daniel Kahn Gillmor2ed81732015-04-03 13:09:24 -0400548 goto exit;
549 }
Paul Bakker40ce79f2013-09-15 17:43:54 +0200550 }
551
552 ret = 0;
553
554exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200555#if defined(MBEDTLS_PEM_PARSE_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100556 mbedtls_pem_free(&pem);
Paul Bakker40ce79f2013-09-15 17:43:54 +0200557#endif
Gilles Peskine449bd832023-01-11 14:50:10 +0100558 if (ret != 0) {
559 mbedtls_dhm_free(dhm);
560 }
Paul Bakker40ce79f2013-09-15 17:43:54 +0200561
Gilles Peskine449bd832023-01-11 14:50:10 +0100562 return ret;
Paul Bakker40ce79f2013-09-15 17:43:54 +0200563}
564
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200565#if defined(MBEDTLS_FS_IO)
Paul Bakker40ce79f2013-09-15 17:43:54 +0200566/*
567 * Load all data from a file into a given buffer.
Manuel Pégourié-Gonnard43b37cb2015-05-12 11:20:10 +0200568 *
569 * The file is expected to contain either PEM or DER encoded data.
570 * A terminating null byte is always appended. It is included in the announced
571 * length only if the data looks like it is PEM encoded.
Paul Bakker40ce79f2013-09-15 17:43:54 +0200572 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100573static int load_file(const char *path, unsigned char **buf, size_t *n)
Paul Bakker40ce79f2013-09-15 17:43:54 +0200574{
575 FILE *f;
576 long size;
577
Gilles Peskine449bd832023-01-11 14:50:10 +0100578 if ((f = fopen(path, "rb")) == NULL) {
579 return MBEDTLS_ERR_DHM_FILE_IO_ERROR;
580 }
Gilles Peskineda0913b2022-06-30 17:03:40 +0200581 /* The data loaded here is public, so don't bother disabling buffering. */
Paul Bakker40ce79f2013-09-15 17:43:54 +0200582
Gilles Peskine449bd832023-01-11 14:50:10 +0100583 fseek(f, 0, SEEK_END);
584 if ((size = ftell(f)) == -1) {
585 fclose(f);
586 return MBEDTLS_ERR_DHM_FILE_IO_ERROR;
Paul Bakker40ce79f2013-09-15 17:43:54 +0200587 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100588 fseek(f, 0, SEEK_SET);
Paul Bakker40ce79f2013-09-15 17:43:54 +0200589
590 *n = (size_t) size;
591
Gilles Peskine449bd832023-01-11 14:50:10 +0100592 if (*n + 1 == 0 ||
593 (*buf = mbedtls_calloc(1, *n + 1)) == NULL) {
594 fclose(f);
595 return MBEDTLS_ERR_DHM_ALLOC_FAILED;
Paul Bakker40ce79f2013-09-15 17:43:54 +0200596 }
597
Gilles Peskine449bd832023-01-11 14:50:10 +0100598 if (fread(*buf, 1, *n, f) != *n) {
599 fclose(f);
Andres Amaya Garciabdbca7b2017-06-23 16:23:21 +0100600
Tom Cosgroveca8c61b2023-07-17 15:17:40 +0100601 mbedtls_zeroize_and_free(*buf, *n + 1);
Andres Amaya Garciabdbca7b2017-06-23 16:23:21 +0100602
Gilles Peskine449bd832023-01-11 14:50:10 +0100603 return MBEDTLS_ERR_DHM_FILE_IO_ERROR;
Paul Bakker40ce79f2013-09-15 17:43:54 +0200604 }
605
Gilles Peskine449bd832023-01-11 14:50:10 +0100606 fclose(f);
Paul Bakker40ce79f2013-09-15 17:43:54 +0200607
608 (*buf)[*n] = '\0';
609
Gilles Peskine449bd832023-01-11 14:50:10 +0100610 if (strstr((const char *) *buf, "-----BEGIN ") != NULL) {
Manuel Pégourié-Gonnard43b37cb2015-05-12 11:20:10 +0200611 ++*n;
Gilles Peskine449bd832023-01-11 14:50:10 +0100612 }
Manuel Pégourié-Gonnard43b37cb2015-05-12 11:20:10 +0200613
Gilles Peskine449bd832023-01-11 14:50:10 +0100614 return 0;
Paul Bakker40ce79f2013-09-15 17:43:54 +0200615}
616
617/*
618 * Load and parse DHM parameters
619 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100620int mbedtls_dhm_parse_dhmfile(mbedtls_dhm_context *dhm, const char *path)
Paul Bakker40ce79f2013-09-15 17:43:54 +0200621{
Janos Follath24eed8d2019-11-22 13:21:35 +0000622 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker40ce79f2013-09-15 17:43:54 +0200623 size_t n;
624 unsigned char *buf;
625
Gilles Peskine449bd832023-01-11 14:50:10 +0100626 if ((ret = load_file(path, &buf, &n)) != 0) {
627 return ret;
628 }
Paul Bakker40ce79f2013-09-15 17:43:54 +0200629
Gilles Peskine449bd832023-01-11 14:50:10 +0100630 ret = mbedtls_dhm_parse_dhm(dhm, buf, n);
Paul Bakker40ce79f2013-09-15 17:43:54 +0200631
Tom Cosgroveca8c61b2023-07-17 15:17:40 +0100632 mbedtls_zeroize_and_free(buf, n);
Paul Bakker40ce79f2013-09-15 17:43:54 +0200633
Gilles Peskine449bd832023-01-11 14:50:10 +0100634 return ret;
Paul Bakker40ce79f2013-09-15 17:43:54 +0200635}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200636#endif /* MBEDTLS_FS_IO */
637#endif /* MBEDTLS_ASN1_PARSE_C */
nirekh0149762fa2017-12-25 06:46:48 +0000638#endif /* MBEDTLS_DHM_ALT */
Paul Bakker40ce79f2013-09-15 17:43:54 +0200639
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200640#if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +0000641
Hanno Becker8b0f9e62019-05-31 17:28:59 +0100642#if defined(MBEDTLS_PEM_PARSE_C)
Manuel Pégourié-Gonnard53585ee2015-06-25 08:52:25 +0200643static const char mbedtls_test_dhm_params[] =
Gilles Peskine449bd832023-01-11 14:50:10 +0100644 "-----BEGIN DH PARAMETERS-----\r\n"
645 "MIGHAoGBAJ419DBEOgmQTzo5qXl5fQcN9TN455wkOL7052HzxxRVMyhYmwQcgJvh\r\n"
646 "1sa18fyfR9OiVEMYglOpkqVoGLN7qd5aQNNi5W7/C+VBdHTBJcGZJyyP5B3qcz32\r\n"
647 "9mLJKudlVudV0Qxk5qUJaPZ/xupz0NyoVpviuiBOI1gNi8ovSXWzAgEC\r\n"
648 "-----END DH PARAMETERS-----\r\n";
Hanno Becker8b0f9e62019-05-31 17:28:59 +0100649#else /* MBEDTLS_PEM_PARSE_C */
650static const char mbedtls_test_dhm_params[] = {
Gilles Peskine449bd832023-01-11 14:50:10 +0100651 0x30, 0x81, 0x87, 0x02, 0x81, 0x81, 0x00, 0x9e, 0x35, 0xf4, 0x30, 0x44,
652 0x3a, 0x09, 0x90, 0x4f, 0x3a, 0x39, 0xa9, 0x79, 0x79, 0x7d, 0x07, 0x0d,
653 0xf5, 0x33, 0x78, 0xe7, 0x9c, 0x24, 0x38, 0xbe, 0xf4, 0xe7, 0x61, 0xf3,
654 0xc7, 0x14, 0x55, 0x33, 0x28, 0x58, 0x9b, 0x04, 0x1c, 0x80, 0x9b, 0xe1,
655 0xd6, 0xc6, 0xb5, 0xf1, 0xfc, 0x9f, 0x47, 0xd3, 0xa2, 0x54, 0x43, 0x18,
656 0x82, 0x53, 0xa9, 0x92, 0xa5, 0x68, 0x18, 0xb3, 0x7b, 0xa9, 0xde, 0x5a,
657 0x40, 0xd3, 0x62, 0xe5, 0x6e, 0xff, 0x0b, 0xe5, 0x41, 0x74, 0x74, 0xc1,
658 0x25, 0xc1, 0x99, 0x27, 0x2c, 0x8f, 0xe4, 0x1d, 0xea, 0x73, 0x3d, 0xf6,
659 0xf6, 0x62, 0xc9, 0x2a, 0xe7, 0x65, 0x56, 0xe7, 0x55, 0xd1, 0x0c, 0x64,
660 0xe6, 0xa5, 0x09, 0x68, 0xf6, 0x7f, 0xc6, 0xea, 0x73, 0xd0, 0xdc, 0xa8,
661 0x56, 0x9b, 0xe2, 0xba, 0x20, 0x4e, 0x23, 0x58, 0x0d, 0x8b, 0xca, 0x2f,
662 0x49, 0x75, 0xb3, 0x02, 0x01, 0x02
663};
Hanno Becker8b0f9e62019-05-31 17:28:59 +0100664#endif /* MBEDTLS_PEM_PARSE_C */
Manuel Pégourié-Gonnard53585ee2015-06-25 08:52:25 +0200665
Gilles Peskine449bd832023-01-11 14:50:10 +0100666static const size_t mbedtls_test_dhm_params_len = sizeof(mbedtls_test_dhm_params);
Paul Bakker40ce79f2013-09-15 17:43:54 +0200667
Paul Bakker5121ce52009-01-03 21:22:43 +0000668/*
669 * Checkup routine
670 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100671int mbedtls_dhm_self_test(int verbose)
Paul Bakker5121ce52009-01-03 21:22:43 +0000672{
Janos Follath24eed8d2019-11-22 13:21:35 +0000673 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200674 mbedtls_dhm_context dhm;
Paul Bakker40ce79f2013-09-15 17:43:54 +0200675
Gilles Peskine449bd832023-01-11 14:50:10 +0100676 mbedtls_dhm_init(&dhm);
Paul Bakker8f870b02014-06-20 13:32:38 +0200677
Gilles Peskine449bd832023-01-11 14:50:10 +0100678 if (verbose != 0) {
679 mbedtls_printf(" DHM parameter load: ");
680 }
Paul Bakker40ce79f2013-09-15 17:43:54 +0200681
Gilles Peskine449bd832023-01-11 14:50:10 +0100682 if ((ret = mbedtls_dhm_parse_dhm(&dhm,
683 (const unsigned char *) mbedtls_test_dhm_params,
684 mbedtls_test_dhm_params_len)) != 0) {
685 if (verbose != 0) {
686 mbedtls_printf("failed\n");
687 }
Paul Bakker40ce79f2013-09-15 17:43:54 +0200688
Manuel Pégourié-Gonnardb196fc22014-07-09 16:53:29 +0200689 ret = 1;
Paul Bakker8f870b02014-06-20 13:32:38 +0200690 goto exit;
Paul Bakker40ce79f2013-09-15 17:43:54 +0200691 }
692
Gilles Peskine449bd832023-01-11 14:50:10 +0100693 if (verbose != 0) {
694 mbedtls_printf("passed\n\n");
695 }
Paul Bakker40ce79f2013-09-15 17:43:54 +0200696
Paul Bakker8f870b02014-06-20 13:32:38 +0200697exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100698 mbedtls_dhm_free(&dhm);
Paul Bakker40ce79f2013-09-15 17:43:54 +0200699
Gilles Peskine449bd832023-01-11 14:50:10 +0100700 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +0000701}
702
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200703#endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +0000704
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200705#endif /* MBEDTLS_DHM_C */