blob: e423657c10f128ef78cf9ec2dadfc013587894e4 [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"
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -050021#include "mbedtls/platform_util.h"
Janos Follath24eed8d2019-11-22 13:21:35 +000022#include "mbedtls/error.h"
Paul Bakker5121ce52009-01-03 21:22:43 +000023
Rich Evans00ab4702015-02-06 13:43:58 +000024#include <string.h>
25
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020026#if defined(MBEDTLS_PEM_PARSE_C)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000027#include "mbedtls/pem.h"
Paul Bakker40ce79f2013-09-15 17:43:54 +020028#endif
29
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020030#if defined(MBEDTLS_ASN1_PARSE_C)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000031#include "mbedtls/asn1.h"
Paul Bakker40ce79f2013-09-15 17:43:54 +020032#endif
33
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000034#include "mbedtls/platform.h"
Paul Bakker40ce79f2013-09-15 17:43:54 +020035
Reuven Levin1f35ca92017-12-07 10:09:32 +000036#if !defined(MBEDTLS_DHM_ALT)
Paul Bakker34617722014-06-13 17:20:13 +020037
Paul Bakker5121ce52009-01-03 21:22:43 +000038/*
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020039 * helper to validate the mbedtls_mpi size and import it
Paul Bakker5121ce52009-01-03 21:22:43 +000040 */
Gilles Peskine449bd832023-01-11 14:50:10 +010041static int dhm_read_bignum(mbedtls_mpi *X,
42 unsigned char **p,
43 const unsigned char *end)
Paul Bakker5121ce52009-01-03 21:22:43 +000044{
45 int ret, n;
46
Gilles Peskine449bd832023-01-11 14:50:10 +010047 if (end - *p < 2) {
48 return MBEDTLS_ERR_DHM_BAD_INPUT_DATA;
49 }
Paul Bakker5121ce52009-01-03 21:22:43 +000050
Gilles Peskine449bd832023-01-11 14:50:10 +010051 n = ((*p)[0] << 8) | (*p)[1];
Paul Bakker5121ce52009-01-03 21:22:43 +000052 (*p) += 2;
53
Dave Rodgmane4a6f5a2023-11-04 12:20:09 +000054 if ((size_t) (end - *p) < (size_t) n) {
Gilles Peskine449bd832023-01-11 14:50:10 +010055 return MBEDTLS_ERR_DHM_BAD_INPUT_DATA;
56 }
Paul Bakker5121ce52009-01-03 21:22:43 +000057
Gilles Peskine449bd832023-01-11 14:50:10 +010058 if ((ret = mbedtls_mpi_read_binary(X, *p, n)) != 0) {
59 return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_DHM_READ_PARAMS_FAILED, ret);
60 }
Paul Bakker5121ce52009-01-03 21:22:43 +000061
62 (*p) += n;
63
Gilles Peskine449bd832023-01-11 14:50:10 +010064 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +000065}
66
67/*
Paul Bakkeraec37cb2012-04-26 18:59:59 +000068 * Verify sanity of parameter with regards to P
Paul Bakker345a6fe2011-02-28 21:20:02 +000069 *
Paul Bakkeraec37cb2012-04-26 18:59:59 +000070 * Parameter should be: 2 <= public_param <= P - 2
Paul Bakker345a6fe2011-02-28 21:20:02 +000071 *
Janos Follathaa325d72017-09-20 15:33:24 +010072 * This means that we need to return an error if
Janos Follath1ad1c6d2017-09-21 09:02:11 +010073 * public_param < 2 or public_param > P-2
Janos Follathaa325d72017-09-20 15:33:24 +010074 *
Paul Bakker345a6fe2011-02-28 21:20:02 +000075 * For more information on the attack, see:
76 * http://www.cl.cam.ac.uk/~rja14/Papers/psandqs.pdf
77 * http://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2005-2643
Paul Bakkerc47840e2011-02-20 16:37:30 +000078 */
Gilles Peskine449bd832023-01-11 14:50:10 +010079static int dhm_check_range(const mbedtls_mpi *param, const mbedtls_mpi *P)
Paul Bakkerc47840e2011-02-20 16:37:30 +000080{
Gilles Peskine8e38acc2021-03-31 22:56:43 +020081 mbedtls_mpi U;
Janos Follathaa325d72017-09-20 15:33:24 +010082 int ret = 0;
Paul Bakkerc47840e2011-02-20 16:37:30 +000083
Gilles Peskine449bd832023-01-11 14:50:10 +010084 mbedtls_mpi_init(&U);
Paul Bakker3d8fb632014-04-17 12:42:41 +020085
Gilles Peskine449bd832023-01-11 14:50:10 +010086 MBEDTLS_MPI_CHK(mbedtls_mpi_sub_int(&U, P, 2));
Paul Bakkerc47840e2011-02-20 16:37:30 +000087
Gilles Peskine449bd832023-01-11 14:50:10 +010088 if (mbedtls_mpi_cmp_int(param, 2) < 0 ||
89 mbedtls_mpi_cmp_mpi(param, &U) > 0) {
Janos Follathaa325d72017-09-20 15:33:24 +010090 ret = MBEDTLS_ERR_DHM_BAD_INPUT_DATA;
Paul Bakkerc47840e2011-02-20 16:37:30 +000091 }
92
Paul Bakker3d8fb632014-04-17 12:42:41 +020093cleanup:
Gilles Peskine449bd832023-01-11 14:50:10 +010094 mbedtls_mpi_free(&U);
95 return ret;
Paul Bakkerc47840e2011-02-20 16:37:30 +000096}
97
Gilles Peskine449bd832023-01-11 14:50:10 +010098void mbedtls_dhm_init(mbedtls_dhm_context *ctx)
Paul Bakker8f870b02014-06-20 13:32:38 +020099{
Gilles Peskine449bd832023-01-11 14:50:10 +0100100 memset(ctx, 0, sizeof(mbedtls_dhm_context));
Paul Bakker8f870b02014-06-20 13:32:38 +0200101}
102
Gilles Peskine449bd832023-01-11 14:50:10 +0100103size_t mbedtls_dhm_get_bitlen(const mbedtls_dhm_context *ctx)
Gilles Peskine487bbf62021-05-27 22:17:07 +0200104{
Gilles Peskine449bd832023-01-11 14:50:10 +0100105 return mbedtls_mpi_bitlen(&ctx->P);
Gilles Peskine487bbf62021-05-27 22:17:07 +0200106}
107
Gilles Peskine449bd832023-01-11 14:50:10 +0100108size_t mbedtls_dhm_get_len(const mbedtls_dhm_context *ctx)
Gilles Peskine487bbf62021-05-27 22:17:07 +0200109{
Gilles Peskine449bd832023-01-11 14:50:10 +0100110 return mbedtls_mpi_size(&ctx->P);
Gilles Peskine487bbf62021-05-27 22:17:07 +0200111}
112
Gilles Peskine449bd832023-01-11 14:50:10 +0100113int mbedtls_dhm_get_value(const mbedtls_dhm_context *ctx,
114 mbedtls_dhm_parameter param,
115 mbedtls_mpi *dest)
Gilles Peskine71acc6e2021-05-27 22:50:53 +0200116{
117 const mbedtls_mpi *src = NULL;
Gilles Peskine449bd832023-01-11 14:50:10 +0100118 switch (param) {
Gilles Peskine71acc6e2021-05-27 22:50:53 +0200119 case MBEDTLS_DHM_PARAM_P:
120 src = &ctx->P;
121 break;
122 case MBEDTLS_DHM_PARAM_G:
123 src = &ctx->G;
124 break;
125 case MBEDTLS_DHM_PARAM_X:
126 src = &ctx->X;
127 break;
128 case MBEDTLS_DHM_PARAM_GX:
129 src = &ctx->GX;
130 break;
131 case MBEDTLS_DHM_PARAM_GY:
132 src = &ctx->GY;
133 break;
134 case MBEDTLS_DHM_PARAM_K:
135 src = &ctx->K;
136 break;
137 default:
Gilles Peskine449bd832023-01-11 14:50:10 +0100138 return MBEDTLS_ERR_DHM_BAD_INPUT_DATA;
Gilles Peskine71acc6e2021-05-27 22:50:53 +0200139 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100140 return mbedtls_mpi_copy(dest, src);
Gilles Peskine71acc6e2021-05-27 22:50:53 +0200141}
142
Paul Bakkerc47840e2011-02-20 16:37:30 +0000143/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000144 * Parse the ServerKeyExchange parameters
145 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100146int mbedtls_dhm_read_params(mbedtls_dhm_context *ctx,
147 unsigned char **p,
148 const unsigned char *end)
Paul Bakker5121ce52009-01-03 21:22:43 +0000149{
Janos Follath24eed8d2019-11-22 13:21:35 +0000150 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker5121ce52009-01-03 21:22:43 +0000151
Gilles Peskine449bd832023-01-11 14:50:10 +0100152 if ((ret = dhm_read_bignum(&ctx->P, p, end)) != 0 ||
153 (ret = dhm_read_bignum(&ctx->G, p, end)) != 0 ||
154 (ret = dhm_read_bignum(&ctx->GY, p, end)) != 0) {
155 return ret;
156 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000157
Gilles Peskine449bd832023-01-11 14:50:10 +0100158 if ((ret = dhm_check_range(&ctx->GY, &ctx->P)) != 0) {
159 return ret;
160 }
Paul Bakker345a6fe2011-02-28 21:20:02 +0000161
Gilles Peskine449bd832023-01-11 14:50:10 +0100162 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000163}
164
Gilles Peskine17f1a262021-03-31 22:48:14 +0200165/*
Gilles Peskineda7ee012021-03-31 23:04:50 +0200166 * Pick a random R in the range [2, M-2] for blinding or key generation.
Gilles Peskine17f1a262021-03-31 22:48:14 +0200167 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100168static int dhm_random_below(mbedtls_mpi *R, const mbedtls_mpi *M,
169 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng)
Gilles Peskine17f1a262021-03-31 22:48:14 +0200170{
Gilles Peskineda7ee012021-03-31 23:04:50 +0200171 int ret;
Gilles Peskine17f1a262021-03-31 22:48:14 +0200172
Gilles Peskine449bd832023-01-11 14:50:10 +0100173 MBEDTLS_MPI_CHK(mbedtls_mpi_random(R, 3, M, f_rng, p_rng));
174 MBEDTLS_MPI_CHK(mbedtls_mpi_sub_int(R, R, 1));
Gilles Peskine17f1a262021-03-31 22:48:14 +0200175
176cleanup:
Gilles Peskine449bd832023-01-11 14:50:10 +0100177 return ret;
Gilles Peskine17f1a262021-03-31 22:48:14 +0200178}
179
Gilles Peskine449bd832023-01-11 14:50:10 +0100180static int dhm_make_common(mbedtls_dhm_context *ctx, int x_size,
181 int (*f_rng)(void *, unsigned char *, size_t),
182 void *p_rng)
Paul Bakker5121ce52009-01-03 21:22:43 +0000183{
Gilles Peskine17f1a262021-03-31 22:48:14 +0200184 int ret = 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000185
Gilles Peskine449bd832023-01-11 14:50:10 +0100186 if (mbedtls_mpi_cmp_int(&ctx->P, 0) == 0) {
187 return MBEDTLS_ERR_DHM_BAD_INPUT_DATA;
Paul Bakkeraec37cb2012-04-26 18:59:59 +0000188 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100189 if (x_size < 0) {
190 return MBEDTLS_ERR_DHM_BAD_INPUT_DATA;
191 }
192
193 if ((unsigned) x_size < mbedtls_mpi_size(&ctx->P)) {
194 MBEDTLS_MPI_CHK(mbedtls_mpi_fill_random(&ctx->X, x_size, f_rng, p_rng));
195 } else {
Gilles Peskine17f1a262021-03-31 22:48:14 +0200196 /* Generate X as large as possible ( <= P - 2 ) */
Gilles Peskine449bd832023-01-11 14:50:10 +0100197 ret = dhm_random_below(&ctx->X, &ctx->P, f_rng, p_rng);
198 if (ret == MBEDTLS_ERR_MPI_NOT_ACCEPTABLE) {
199 return MBEDTLS_ERR_DHM_MAKE_PARAMS_FAILED;
200 }
201 if (ret != 0) {
202 return ret;
203 }
Gilles Peskine17f1a262021-03-31 22:48:14 +0200204 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000205
Paul Bakkerff7fe672010-07-18 09:45:05 +0000206 /*
207 * Calculate GX = G^X mod P
208 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100209 MBEDTLS_MPI_CHK(mbedtls_mpi_exp_mod(&ctx->GX, &ctx->G, &ctx->X,
210 &ctx->P, &ctx->RP));
Paul Bakker5121ce52009-01-03 21:22:43 +0000211
Gilles Peskine449bd832023-01-11 14:50:10 +0100212 if ((ret = dhm_check_range(&ctx->GX, &ctx->P)) != 0) {
213 return ret;
214 }
Paul Bakkerc47840e2011-02-20 16:37:30 +0000215
Gilles Peskinecb660f22021-03-31 22:35:13 +0200216cleanup:
Gilles Peskine449bd832023-01-11 14:50:10 +0100217 return ret;
Gilles Peskinecb660f22021-03-31 22:35:13 +0200218}
219
220/*
221 * Setup and write the ServerKeyExchange parameters
222 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100223int mbedtls_dhm_make_params(mbedtls_dhm_context *ctx, int x_size,
224 unsigned char *output, size_t *olen,
225 int (*f_rng)(void *, unsigned char *, size_t),
226 void *p_rng)
Gilles Peskinecb660f22021-03-31 22:35:13 +0200227{
228 int ret;
229 size_t n1, n2, n3;
230 unsigned char *p;
Gilles Peskinecb660f22021-03-31 22:35:13 +0200231
Gilles Peskine449bd832023-01-11 14:50:10 +0100232 ret = dhm_make_common(ctx, x_size, f_rng, p_rng);
233 if (ret != 0) {
Gilles Peskinecb660f22021-03-31 22:35:13 +0200234 goto cleanup;
Gilles Peskine449bd832023-01-11 14:50:10 +0100235 }
Gilles Peskinecb660f22021-03-31 22:35:13 +0200236
Paul Bakker5121ce52009-01-03 21:22:43 +0000237 /*
Gilles Peskine03299dc2021-04-13 22:10:24 +0200238 * Export P, G, GX. RFC 5246 §4.4 states that "leading zero octets are
239 * not required". We omit leading zeros for compactness.
Paul Bakker5121ce52009-01-03 21:22:43 +0000240 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100241#define DHM_MPI_EXPORT(X, n) \
Hanno Beckere71ad122017-09-28 10:32:25 +0100242 do { \
Gilles Peskine449bd832023-01-11 14:50:10 +0100243 MBEDTLS_MPI_CHK(mbedtls_mpi_write_binary((X), \
244 p + 2, \
245 (n))); \
246 *p++ = MBEDTLS_BYTE_1(n); \
247 *p++ = MBEDTLS_BYTE_0(n); \
248 p += (n); \
249 } while (0)
Paul Bakker5121ce52009-01-03 21:22:43 +0000250
Gilles Peskine449bd832023-01-11 14:50:10 +0100251 n1 = mbedtls_mpi_size(&ctx->P);
252 n2 = mbedtls_mpi_size(&ctx->G);
253 n3 = mbedtls_mpi_size(&ctx->GX);
Paul Bakker5121ce52009-01-03 21:22:43 +0000254
255 p = output;
Gilles Peskine449bd832023-01-11 14:50:10 +0100256 DHM_MPI_EXPORT(&ctx->P, n1);
257 DHM_MPI_EXPORT(&ctx->G, n2);
258 DHM_MPI_EXPORT(&ctx->GX, n3);
Paul Bakker5121ce52009-01-03 21:22:43 +0000259
Dave Rodgmane4a6f5a2023-11-04 12:20:09 +0000260 *olen = (size_t) (p - output);
Paul Bakker5121ce52009-01-03 21:22:43 +0000261
Paul Bakker5121ce52009-01-03 21:22:43 +0000262cleanup:
Gilles Peskine449bd832023-01-11 14:50:10 +0100263 if (ret != 0 && ret > -128) {
264 ret = MBEDTLS_ERROR_ADD(MBEDTLS_ERR_DHM_MAKE_PARAMS_FAILED, ret);
265 }
266 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +0000267}
268
269/*
Hanno Becker8880e752017-10-04 13:15:08 +0100270 * Set prime modulus and generator
271 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100272int mbedtls_dhm_set_group(mbedtls_dhm_context *ctx,
273 const mbedtls_mpi *P,
274 const mbedtls_mpi *G)
Hanno Becker8880e752017-10-04 13:15:08 +0100275{
Janos Follath24eed8d2019-11-22 13:21:35 +0000276 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Hanno Becker8880e752017-10-04 13:15:08 +0100277
Gilles Peskine449bd832023-01-11 14:50:10 +0100278 if ((ret = mbedtls_mpi_copy(&ctx->P, P)) != 0 ||
279 (ret = mbedtls_mpi_copy(&ctx->G, G)) != 0) {
280 return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_DHM_SET_GROUP_FAILED, ret);
Hanno Becker8880e752017-10-04 13:15:08 +0100281 }
282
Gilles Peskine449bd832023-01-11 14:50:10 +0100283 return 0;
Hanno Becker8880e752017-10-04 13:15:08 +0100284}
285
286/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000287 * Import the peer's public value G^Y
288 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100289int mbedtls_dhm_read_public(mbedtls_dhm_context *ctx,
290 const unsigned char *input, size_t ilen)
Paul Bakker5121ce52009-01-03 21:22:43 +0000291{
Janos Follath24eed8d2019-11-22 13:21:35 +0000292 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker5121ce52009-01-03 21:22:43 +0000293
Gilles Peskine449bd832023-01-11 14:50:10 +0100294 if (ilen < 1 || ilen > mbedtls_dhm_get_len(ctx)) {
295 return MBEDTLS_ERR_DHM_BAD_INPUT_DATA;
296 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000297
Gilles Peskine449bd832023-01-11 14:50:10 +0100298 if ((ret = mbedtls_mpi_read_binary(&ctx->GY, input, ilen)) != 0) {
299 return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_DHM_READ_PUBLIC_FAILED, ret);
300 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000301
Gilles Peskine449bd832023-01-11 14:50:10 +0100302 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000303}
304
305/*
306 * Create own private value X and export G^X
307 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100308int mbedtls_dhm_make_public(mbedtls_dhm_context *ctx, int x_size,
309 unsigned char *output, size_t olen,
310 int (*f_rng)(void *, unsigned char *, size_t),
311 void *p_rng)
Paul Bakker5121ce52009-01-03 21:22:43 +0000312{
Gilles Peskinecb660f22021-03-31 22:35:13 +0200313 int ret;
Paul Bakker5121ce52009-01-03 21:22:43 +0000314
Gilles Peskine449bd832023-01-11 14:50:10 +0100315 if (olen < 1 || olen > mbedtls_dhm_get_len(ctx)) {
316 return MBEDTLS_ERR_DHM_BAD_INPUT_DATA;
317 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000318
Gilles Peskine449bd832023-01-11 14:50:10 +0100319 ret = dhm_make_common(ctx, x_size, f_rng, p_rng);
320 if (ret == MBEDTLS_ERR_DHM_MAKE_PARAMS_FAILED) {
321 return MBEDTLS_ERR_DHM_MAKE_PUBLIC_FAILED;
322 }
323 if (ret != 0) {
Gilles Peskinecb660f22021-03-31 22:35:13 +0200324 goto cleanup;
Gilles Peskine449bd832023-01-11 14:50:10 +0100325 }
Paul Bakkerc47840e2011-02-20 16:37:30 +0000326
Gilles Peskine449bd832023-01-11 14:50:10 +0100327 MBEDTLS_MPI_CHK(mbedtls_mpi_write_binary(&ctx->GX, output, olen));
Paul Bakker5121ce52009-01-03 21:22:43 +0000328
329cleanup:
Gilles Peskine449bd832023-01-11 14:50:10 +0100330 if (ret != 0 && ret > -128) {
331 ret = MBEDTLS_ERROR_ADD(MBEDTLS_ERR_DHM_MAKE_PUBLIC_FAILED, ret);
332 }
333 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +0000334}
335
Manuel Pégourié-Gonnard9f58c4b2020-06-25 12:34:58 +0200336
337/*
Manuel Pégourié-Gonnard143b5022013-09-04 16:29:59 +0200338 * Use the blinding method and optimisation suggested in section 10 of:
339 * KOCHER, Paul C. Timing attacks on implementations of Diffie-Hellman, RSA,
Manuel Pégourié-Gonnard998930a2015-04-03 13:48:06 +0200340 * DSS, and other systems. In : Advances in Cryptology-CRYPTO'96. Springer
Manuel Pégourié-Gonnard143b5022013-09-04 16:29:59 +0200341 * Berlin Heidelberg, 1996. p. 104-113.
342 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100343static int dhm_update_blinding(mbedtls_dhm_context *ctx,
344 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng)
Manuel Pégourié-Gonnard143b5022013-09-04 16:29:59 +0200345{
Manuel Pégourié-Gonnard9f58c4b2020-06-25 12:34:58 +0200346 int ret;
Manuel Pégourié-Gonnardaf721672020-06-25 12:47:22 +0200347 mbedtls_mpi R;
348
Gilles Peskine449bd832023-01-11 14:50:10 +0100349 mbedtls_mpi_init(&R);
Manuel Pégourié-Gonnard143b5022013-09-04 16:29:59 +0200350
351 /*
Manuel Pégourié-Gonnard15d5de12013-09-17 11:34:11 +0200352 * Don't use any blinding the first time a particular X is used,
353 * but remember it to use blinding next time.
Manuel Pégourié-Gonnard143b5022013-09-04 16:29:59 +0200354 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100355 if (mbedtls_mpi_cmp_mpi(&ctx->X, &ctx->pX) != 0) {
356 MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&ctx->pX, &ctx->X));
357 MBEDTLS_MPI_CHK(mbedtls_mpi_lset(&ctx->Vi, 1));
358 MBEDTLS_MPI_CHK(mbedtls_mpi_lset(&ctx->Vf, 1));
Manuel Pégourié-Gonnarded8a02b2013-09-04 16:39:03 +0200359
Gilles Peskine449bd832023-01-11 14:50:10 +0100360 return 0;
Manuel Pégourié-Gonnard143b5022013-09-04 16:29:59 +0200361 }
362
363 /*
Manuel Pégourié-Gonnard15d5de12013-09-17 11:34:11 +0200364 * Ok, we need blinding. Can we re-use existing values?
365 * If yes, just update them by squaring them.
Manuel Pégourié-Gonnard143b5022013-09-04 16:29:59 +0200366 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100367 if (mbedtls_mpi_cmp_int(&ctx->Vi, 1) != 0) {
368 MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(&ctx->Vi, &ctx->Vi, &ctx->Vi));
369 MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(&ctx->Vi, &ctx->Vi, &ctx->P));
Manuel Pégourié-Gonnard15d5de12013-09-17 11:34:11 +0200370
Gilles Peskine449bd832023-01-11 14:50:10 +0100371 MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(&ctx->Vf, &ctx->Vf, &ctx->Vf));
372 MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(&ctx->Vf, &ctx->Vf, &ctx->P));
Manuel Pégourié-Gonnard15d5de12013-09-17 11:34:11 +0200373
Gilles Peskine449bd832023-01-11 14:50:10 +0100374 return 0;
Manuel Pégourié-Gonnard15d5de12013-09-17 11:34:11 +0200375 }
376
377 /*
378 * We need to generate blinding values from scratch
379 */
380
Gilles Peskine7b2b66e2021-03-31 22:50:57 +0200381 /* Vi = random( 2, P-2 ) */
Gilles Peskine449bd832023-01-11 14:50:10 +0100382 MBEDTLS_MPI_CHK(dhm_random_below(&ctx->Vi, &ctx->P, f_rng, p_rng));
Manuel Pégourié-Gonnard15d5de12013-09-17 11:34:11 +0200383
Manuel Pégourié-Gonnardaf721672020-06-25 12:47:22 +0200384 /* Vf = Vi^-X mod P
385 * First compute Vi^-1 = R * (R Vi)^-1, (avoiding leaks from inv_mod),
386 * then elevate to the Xth power. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100387 MBEDTLS_MPI_CHK(dhm_random_below(&R, &ctx->P, f_rng, p_rng));
388 MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(&ctx->Vf, &ctx->Vi, &R));
389 MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(&ctx->Vf, &ctx->Vf, &ctx->P));
390 MBEDTLS_MPI_CHK(mbedtls_mpi_inv_mod(&ctx->Vf, &ctx->Vf, &ctx->P));
391 MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(&ctx->Vf, &ctx->Vf, &R));
392 MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(&ctx->Vf, &ctx->Vf, &ctx->P));
Manuel Pégourié-Gonnard15d5de12013-09-17 11:34:11 +0200393
Gilles Peskine449bd832023-01-11 14:50:10 +0100394 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 +0200395
Manuel Pégourié-Gonnard143b5022013-09-04 16:29:59 +0200396cleanup:
Gilles Peskine449bd832023-01-11 14:50:10 +0100397 mbedtls_mpi_free(&R);
Manuel Pégourié-Gonnardaf721672020-06-25 12:47:22 +0200398
Gilles Peskine449bd832023-01-11 14:50:10 +0100399 return ret;
Manuel Pégourié-Gonnard143b5022013-09-04 16:29:59 +0200400}
401
402/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000403 * Derive and export the shared secret (G^Y)^X mod P
404 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100405int mbedtls_dhm_calc_secret(mbedtls_dhm_context *ctx,
406 unsigned char *output, size_t output_size, size_t *olen,
407 int (*f_rng)(void *, unsigned char *, size_t),
408 void *p_rng)
Paul Bakker5121ce52009-01-03 21:22:43 +0000409{
Janos Follath24eed8d2019-11-22 13:21:35 +0000410 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200411 mbedtls_mpi GYb;
Manuel Pégourié-Gonnard2d627642013-09-04 14:22:07 +0200412
Gilles Peskine449bd832023-01-11 14:50:10 +0100413 if (f_rng == NULL) {
414 return MBEDTLS_ERR_DHM_BAD_INPUT_DATA;
415 }
Manuel Pégourié-Gonnard1a877222021-06-15 11:29:26 +0200416
Gilles Peskine449bd832023-01-11 14:50:10 +0100417 if (output_size < mbedtls_dhm_get_len(ctx)) {
418 return MBEDTLS_ERR_DHM_BAD_INPUT_DATA;
419 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000420
Gilles Peskine449bd832023-01-11 14:50:10 +0100421 if ((ret = dhm_check_range(&ctx->GY, &ctx->P)) != 0) {
422 return ret;
423 }
Paul Bakkerc47840e2011-02-20 16:37:30 +0000424
Gilles Peskine449bd832023-01-11 14:50:10 +0100425 mbedtls_mpi_init(&GYb);
Manuel Pégourié-Gonnard143b5022013-09-04 16:29:59 +0200426
427 /* Blind peer's value */
Gilles Peskine449bd832023-01-11 14:50:10 +0100428 MBEDTLS_MPI_CHK(dhm_update_blinding(ctx, f_rng, p_rng));
429 MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(&GYb, &ctx->GY, &ctx->Vi));
430 MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(&GYb, &GYb, &ctx->P));
Manuel Pégourié-Gonnard143b5022013-09-04 16:29:59 +0200431
432 /* Do modular exponentiation */
Gilles Peskine449bd832023-01-11 14:50:10 +0100433 MBEDTLS_MPI_CHK(mbedtls_mpi_exp_mod(&ctx->K, &GYb, &ctx->X,
434 &ctx->P, &ctx->RP));
Manuel Pégourié-Gonnard143b5022013-09-04 16:29:59 +0200435
436 /* Unblind secret value */
Gilles Peskine449bd832023-01-11 14:50:10 +0100437 MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(&ctx->K, &ctx->K, &ctx->Vf));
438 MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(&ctx->K, &ctx->K, &ctx->P));
Manuel Pégourié-Gonnard143b5022013-09-04 16:29:59 +0200439
Gilles Peskine03299dc2021-04-13 22:10:24 +0200440 /* Output the secret without any leading zero byte. This is mandatory
441 * for TLS per RFC 5246 §8.1.2. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100442 *olen = mbedtls_mpi_size(&ctx->K);
443 MBEDTLS_MPI_CHK(mbedtls_mpi_write_binary(&ctx->K, output, *olen));
Paul Bakker5121ce52009-01-03 21:22:43 +0000444
445cleanup:
Gilles Peskine449bd832023-01-11 14:50:10 +0100446 mbedtls_mpi_free(&GYb);
Paul Bakker5121ce52009-01-03 21:22:43 +0000447
Gilles Peskine449bd832023-01-11 14:50:10 +0100448 if (ret != 0) {
449 return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_DHM_CALC_SECRET_FAILED, ret);
450 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000451
Gilles Peskine449bd832023-01-11 14:50:10 +0100452 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000453}
454
455/*
456 * Free the components of a DHM key
457 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100458void mbedtls_dhm_free(mbedtls_dhm_context *ctx)
Paul Bakker5121ce52009-01-03 21:22:43 +0000459{
Gilles Peskine449bd832023-01-11 14:50:10 +0100460 if (ctx == NULL) {
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500461 return;
Gilles Peskine449bd832023-01-11 14:50:10 +0100462 }
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500463
Gilles Peskine449bd832023-01-11 14:50:10 +0100464 mbedtls_mpi_free(&ctx->pX);
465 mbedtls_mpi_free(&ctx->Vf);
466 mbedtls_mpi_free(&ctx->Vi);
467 mbedtls_mpi_free(&ctx->RP);
468 mbedtls_mpi_free(&ctx->K);
469 mbedtls_mpi_free(&ctx->GY);
470 mbedtls_mpi_free(&ctx->GX);
471 mbedtls_mpi_free(&ctx->X);
472 mbedtls_mpi_free(&ctx->G);
473 mbedtls_mpi_free(&ctx->P);
Manuel Pégourié-Gonnardb72b4ed2013-09-13 13:55:26 +0200474
Gilles Peskine449bd832023-01-11 14:50:10 +0100475 mbedtls_platform_zeroize(ctx, sizeof(mbedtls_dhm_context));
Paul Bakker5121ce52009-01-03 21:22:43 +0000476}
477
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200478#if defined(MBEDTLS_ASN1_PARSE_C)
Paul Bakker40ce79f2013-09-15 17:43:54 +0200479/*
480 * Parse DHM parameters
481 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100482int mbedtls_dhm_parse_dhm(mbedtls_dhm_context *dhm, const unsigned char *dhmin,
483 size_t dhminlen)
Paul Bakker40ce79f2013-09-15 17:43:54 +0200484{
Janos Follath24eed8d2019-11-22 13:21:35 +0000485 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker40ce79f2013-09-15 17:43:54 +0200486 size_t len;
487 unsigned char *p, *end;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200488#if defined(MBEDTLS_PEM_PARSE_C)
489 mbedtls_pem_context pem;
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500490#endif /* MBEDTLS_PEM_PARSE_C */
Paul Bakker40ce79f2013-09-15 17:43:54 +0200491
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500492#if defined(MBEDTLS_PEM_PARSE_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100493 mbedtls_pem_init(&pem);
Paul Bakker40ce79f2013-09-15 17:43:54 +0200494
Manuel Pégourié-Gonnard43b37cb2015-05-12 11:20:10 +0200495 /* Avoid calling mbedtls_pem_read_buffer() on non-null-terminated string */
Gilles Peskine449bd832023-01-11 14:50:10 +0100496 if (dhminlen == 0 || dhmin[dhminlen - 1] != '\0') {
Manuel Pégourié-Gonnard43b37cb2015-05-12 11:20:10 +0200497 ret = MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT;
Gilles Peskine449bd832023-01-11 14:50:10 +0100498 } else {
499 ret = mbedtls_pem_read_buffer(&pem,
500 "-----BEGIN DH PARAMETERS-----",
501 "-----END DH PARAMETERS-----",
502 dhmin, NULL, 0, &dhminlen);
503 }
Paul Bakker40ce79f2013-09-15 17:43:54 +0200504
Gilles Peskine449bd832023-01-11 14:50:10 +0100505 if (ret == 0) {
Paul Bakker40ce79f2013-09-15 17:43:54 +0200506 /*
507 * Was PEM encoded
508 */
509 dhminlen = pem.buflen;
Gilles Peskine449bd832023-01-11 14:50:10 +0100510 } else if (ret != MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT) {
Paul Bakker40ce79f2013-09-15 17:43:54 +0200511 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100512 }
Paul Bakker40ce79f2013-09-15 17:43:54 +0200513
Gilles Peskine449bd832023-01-11 14:50:10 +0100514 p = (ret == 0) ? pem.buf : (unsigned char *) dhmin;
Paul Bakker40ce79f2013-09-15 17:43:54 +0200515#else
516 p = (unsigned char *) dhmin;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200517#endif /* MBEDTLS_PEM_PARSE_C */
Paul Bakker40ce79f2013-09-15 17:43:54 +0200518 end = p + dhminlen;
519
520 /*
521 * DHParams ::= SEQUENCE {
Daniel Kahn Gillmor2ed81732015-04-03 13:09:24 -0400522 * prime INTEGER, -- P
523 * generator INTEGER, -- g
524 * privateValueLength INTEGER OPTIONAL
Paul Bakker40ce79f2013-09-15 17:43:54 +0200525 * }
526 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100527 if ((ret = mbedtls_asn1_get_tag(&p, end, &len,
528 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) {
529 ret = MBEDTLS_ERROR_ADD(MBEDTLS_ERR_DHM_INVALID_FORMAT, ret);
Paul Bakker40ce79f2013-09-15 17:43:54 +0200530 goto exit;
531 }
532
533 end = p + len;
534
Gilles Peskine449bd832023-01-11 14:50:10 +0100535 if ((ret = mbedtls_asn1_get_mpi(&p, end, &dhm->P)) != 0 ||
536 (ret = mbedtls_asn1_get_mpi(&p, end, &dhm->G)) != 0) {
537 ret = MBEDTLS_ERROR_ADD(MBEDTLS_ERR_DHM_INVALID_FORMAT, ret);
Paul Bakker40ce79f2013-09-15 17:43:54 +0200538 goto exit;
539 }
540
Gilles Peskine449bd832023-01-11 14:50:10 +0100541 if (p != end) {
Manuel Pégourié-Gonnardde9b3632015-04-17 20:06:31 +0200542 /* This might be the optional privateValueLength.
543 * If so, we can cleanly discard it */
544 mbedtls_mpi rec;
Gilles Peskine449bd832023-01-11 14:50:10 +0100545 mbedtls_mpi_init(&rec);
546 ret = mbedtls_asn1_get_mpi(&p, end, &rec);
547 mbedtls_mpi_free(&rec);
548 if (ret != 0) {
549 ret = MBEDTLS_ERROR_ADD(MBEDTLS_ERR_DHM_INVALID_FORMAT, ret);
Daniel Kahn Gillmor2ed81732015-04-03 13:09:24 -0400550 goto exit;
551 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100552 if (p != end) {
553 ret = MBEDTLS_ERROR_ADD(MBEDTLS_ERR_DHM_INVALID_FORMAT,
554 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
Daniel Kahn Gillmor2ed81732015-04-03 13:09:24 -0400555 goto exit;
556 }
Paul Bakker40ce79f2013-09-15 17:43:54 +0200557 }
558
559 ret = 0;
560
561exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200562#if defined(MBEDTLS_PEM_PARSE_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100563 mbedtls_pem_free(&pem);
Paul Bakker40ce79f2013-09-15 17:43:54 +0200564#endif
Gilles Peskine449bd832023-01-11 14:50:10 +0100565 if (ret != 0) {
566 mbedtls_dhm_free(dhm);
567 }
Paul Bakker40ce79f2013-09-15 17:43:54 +0200568
Gilles Peskine449bd832023-01-11 14:50:10 +0100569 return ret;
Paul Bakker40ce79f2013-09-15 17:43:54 +0200570}
571
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200572#if defined(MBEDTLS_FS_IO)
Paul Bakker40ce79f2013-09-15 17:43:54 +0200573/*
574 * Load all data from a file into a given buffer.
Manuel Pégourié-Gonnard43b37cb2015-05-12 11:20:10 +0200575 *
576 * The file is expected to contain either PEM or DER encoded data.
577 * A terminating null byte is always appended. It is included in the announced
578 * length only if the data looks like it is PEM encoded.
Paul Bakker40ce79f2013-09-15 17:43:54 +0200579 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100580static int load_file(const char *path, unsigned char **buf, size_t *n)
Paul Bakker40ce79f2013-09-15 17:43:54 +0200581{
582 FILE *f;
583 long size;
584
Gilles Peskine449bd832023-01-11 14:50:10 +0100585 if ((f = fopen(path, "rb")) == NULL) {
586 return MBEDTLS_ERR_DHM_FILE_IO_ERROR;
587 }
Gilles Peskineda0913b2022-06-30 17:03:40 +0200588 /* The data loaded here is public, so don't bother disabling buffering. */
Paul Bakker40ce79f2013-09-15 17:43:54 +0200589
Gilles Peskine449bd832023-01-11 14:50:10 +0100590 fseek(f, 0, SEEK_END);
591 if ((size = ftell(f)) == -1) {
592 fclose(f);
593 return MBEDTLS_ERR_DHM_FILE_IO_ERROR;
Paul Bakker40ce79f2013-09-15 17:43:54 +0200594 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100595 fseek(f, 0, SEEK_SET);
Paul Bakker40ce79f2013-09-15 17:43:54 +0200596
597 *n = (size_t) size;
598
Gilles Peskine449bd832023-01-11 14:50:10 +0100599 if (*n + 1 == 0 ||
600 (*buf = mbedtls_calloc(1, *n + 1)) == NULL) {
601 fclose(f);
602 return MBEDTLS_ERR_DHM_ALLOC_FAILED;
Paul Bakker40ce79f2013-09-15 17:43:54 +0200603 }
604
Gilles Peskine449bd832023-01-11 14:50:10 +0100605 if (fread(*buf, 1, *n, f) != *n) {
606 fclose(f);
Andres Amaya Garciabdbca7b2017-06-23 16:23:21 +0100607
Tom Cosgroveca8c61b2023-07-17 15:17:40 +0100608 mbedtls_zeroize_and_free(*buf, *n + 1);
Andres Amaya Garciabdbca7b2017-06-23 16:23:21 +0100609
Gilles Peskine449bd832023-01-11 14:50:10 +0100610 return MBEDTLS_ERR_DHM_FILE_IO_ERROR;
Paul Bakker40ce79f2013-09-15 17:43:54 +0200611 }
612
Gilles Peskine449bd832023-01-11 14:50:10 +0100613 fclose(f);
Paul Bakker40ce79f2013-09-15 17:43:54 +0200614
615 (*buf)[*n] = '\0';
616
Gilles Peskine449bd832023-01-11 14:50:10 +0100617 if (strstr((const char *) *buf, "-----BEGIN ") != NULL) {
Manuel Pégourié-Gonnard43b37cb2015-05-12 11:20:10 +0200618 ++*n;
Gilles Peskine449bd832023-01-11 14:50:10 +0100619 }
Manuel Pégourié-Gonnard43b37cb2015-05-12 11:20:10 +0200620
Gilles Peskine449bd832023-01-11 14:50:10 +0100621 return 0;
Paul Bakker40ce79f2013-09-15 17:43:54 +0200622}
623
624/*
625 * Load and parse DHM parameters
626 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100627int mbedtls_dhm_parse_dhmfile(mbedtls_dhm_context *dhm, const char *path)
Paul Bakker40ce79f2013-09-15 17:43:54 +0200628{
Janos Follath24eed8d2019-11-22 13:21:35 +0000629 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker40ce79f2013-09-15 17:43:54 +0200630 size_t n;
631 unsigned char *buf;
632
Gilles Peskine449bd832023-01-11 14:50:10 +0100633 if ((ret = load_file(path, &buf, &n)) != 0) {
634 return ret;
635 }
Paul Bakker40ce79f2013-09-15 17:43:54 +0200636
Gilles Peskine449bd832023-01-11 14:50:10 +0100637 ret = mbedtls_dhm_parse_dhm(dhm, buf, n);
Paul Bakker40ce79f2013-09-15 17:43:54 +0200638
Tom Cosgroveca8c61b2023-07-17 15:17:40 +0100639 mbedtls_zeroize_and_free(buf, n);
Paul Bakker40ce79f2013-09-15 17:43:54 +0200640
Gilles Peskine449bd832023-01-11 14:50:10 +0100641 return ret;
Paul Bakker40ce79f2013-09-15 17:43:54 +0200642}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200643#endif /* MBEDTLS_FS_IO */
644#endif /* MBEDTLS_ASN1_PARSE_C */
nirekh0149762fa2017-12-25 06:46:48 +0000645#endif /* MBEDTLS_DHM_ALT */
Paul Bakker40ce79f2013-09-15 17:43:54 +0200646
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200647#if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +0000648
Hanno Becker8b0f9e62019-05-31 17:28:59 +0100649#if defined(MBEDTLS_PEM_PARSE_C)
Manuel Pégourié-Gonnard53585ee2015-06-25 08:52:25 +0200650static const char mbedtls_test_dhm_params[] =
Gilles Peskine449bd832023-01-11 14:50:10 +0100651 "-----BEGIN DH PARAMETERS-----\r\n"
652 "MIGHAoGBAJ419DBEOgmQTzo5qXl5fQcN9TN455wkOL7052HzxxRVMyhYmwQcgJvh\r\n"
653 "1sa18fyfR9OiVEMYglOpkqVoGLN7qd5aQNNi5W7/C+VBdHTBJcGZJyyP5B3qcz32\r\n"
654 "9mLJKudlVudV0Qxk5qUJaPZ/xupz0NyoVpviuiBOI1gNi8ovSXWzAgEC\r\n"
655 "-----END DH PARAMETERS-----\r\n";
Hanno Becker8b0f9e62019-05-31 17:28:59 +0100656#else /* MBEDTLS_PEM_PARSE_C */
657static const char mbedtls_test_dhm_params[] = {
Gilles Peskine449bd832023-01-11 14:50:10 +0100658 0x30, 0x81, 0x87, 0x02, 0x81, 0x81, 0x00, 0x9e, 0x35, 0xf4, 0x30, 0x44,
659 0x3a, 0x09, 0x90, 0x4f, 0x3a, 0x39, 0xa9, 0x79, 0x79, 0x7d, 0x07, 0x0d,
660 0xf5, 0x33, 0x78, 0xe7, 0x9c, 0x24, 0x38, 0xbe, 0xf4, 0xe7, 0x61, 0xf3,
661 0xc7, 0x14, 0x55, 0x33, 0x28, 0x58, 0x9b, 0x04, 0x1c, 0x80, 0x9b, 0xe1,
662 0xd6, 0xc6, 0xb5, 0xf1, 0xfc, 0x9f, 0x47, 0xd3, 0xa2, 0x54, 0x43, 0x18,
663 0x82, 0x53, 0xa9, 0x92, 0xa5, 0x68, 0x18, 0xb3, 0x7b, 0xa9, 0xde, 0x5a,
664 0x40, 0xd3, 0x62, 0xe5, 0x6e, 0xff, 0x0b, 0xe5, 0x41, 0x74, 0x74, 0xc1,
665 0x25, 0xc1, 0x99, 0x27, 0x2c, 0x8f, 0xe4, 0x1d, 0xea, 0x73, 0x3d, 0xf6,
666 0xf6, 0x62, 0xc9, 0x2a, 0xe7, 0x65, 0x56, 0xe7, 0x55, 0xd1, 0x0c, 0x64,
667 0xe6, 0xa5, 0x09, 0x68, 0xf6, 0x7f, 0xc6, 0xea, 0x73, 0xd0, 0xdc, 0xa8,
668 0x56, 0x9b, 0xe2, 0xba, 0x20, 0x4e, 0x23, 0x58, 0x0d, 0x8b, 0xca, 0x2f,
669 0x49, 0x75, 0xb3, 0x02, 0x01, 0x02
670};
Hanno Becker8b0f9e62019-05-31 17:28:59 +0100671#endif /* MBEDTLS_PEM_PARSE_C */
Manuel Pégourié-Gonnard53585ee2015-06-25 08:52:25 +0200672
Gilles Peskine449bd832023-01-11 14:50:10 +0100673static const size_t mbedtls_test_dhm_params_len = sizeof(mbedtls_test_dhm_params);
Paul Bakker40ce79f2013-09-15 17:43:54 +0200674
Paul Bakker5121ce52009-01-03 21:22:43 +0000675/*
676 * Checkup routine
677 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100678int mbedtls_dhm_self_test(int verbose)
Paul Bakker5121ce52009-01-03 21:22:43 +0000679{
Janos Follath24eed8d2019-11-22 13:21:35 +0000680 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200681 mbedtls_dhm_context dhm;
Paul Bakker40ce79f2013-09-15 17:43:54 +0200682
Gilles Peskine449bd832023-01-11 14:50:10 +0100683 mbedtls_dhm_init(&dhm);
Paul Bakker8f870b02014-06-20 13:32:38 +0200684
Gilles Peskine449bd832023-01-11 14:50:10 +0100685 if (verbose != 0) {
686 mbedtls_printf(" DHM parameter load: ");
687 }
Paul Bakker40ce79f2013-09-15 17:43:54 +0200688
Gilles Peskine449bd832023-01-11 14:50:10 +0100689 if ((ret = mbedtls_dhm_parse_dhm(&dhm,
690 (const unsigned char *) mbedtls_test_dhm_params,
691 mbedtls_test_dhm_params_len)) != 0) {
692 if (verbose != 0) {
693 mbedtls_printf("failed\n");
694 }
Paul Bakker40ce79f2013-09-15 17:43:54 +0200695
Manuel Pégourié-Gonnardb196fc22014-07-09 16:53:29 +0200696 ret = 1;
Paul Bakker8f870b02014-06-20 13:32:38 +0200697 goto exit;
Paul Bakker40ce79f2013-09-15 17:43:54 +0200698 }
699
Gilles Peskine449bd832023-01-11 14:50:10 +0100700 if (verbose != 0) {
701 mbedtls_printf("passed\n\n");
702 }
Paul Bakker40ce79f2013-09-15 17:43:54 +0200703
Paul Bakker8f870b02014-06-20 13:32:38 +0200704exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100705 mbedtls_dhm_free(&dhm);
Paul Bakker40ce79f2013-09-15 17:43:54 +0200706
Gilles Peskine449bd832023-01-11 14:50:10 +0100707 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +0000708}
709
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200710#endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +0000711
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200712#endif /* MBEDTLS_DHM_C */