blob: c6f955ee42685ae711c56870688b37ff27b87562 [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
David Horstmannceeaeb92023-01-05 15:44:23 +000050#define DHM_VALIDATE_RET(cond) \
51 MBEDTLS_INTERNAL_VALIDATE_RET(cond, MBEDTLS_ERR_DHM_BAD_INPUT_DATA)
52#define DHM_VALIDATE(cond) \
53 MBEDTLS_INTERNAL_VALIDATE(cond)
Andrzej Kurekc470b6b2019-01-31 08:20:20 -050054
Paul Bakker5121ce52009-01-03 21:22:43 +000055/*
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020056 * helper to validate the mbedtls_mpi size and import it
Paul Bakker5121ce52009-01-03 21:22:43 +000057 */
David Horstmannceeaeb92023-01-05 15:44:23 +000058static int dhm_read_bignum(mbedtls_mpi *X,
59 unsigned char **p,
60 const unsigned char *end)
Paul Bakker5121ce52009-01-03 21:22:43 +000061{
62 int ret, n;
63
David Horstmannceeaeb92023-01-05 15:44:23 +000064 if (end - *p < 2) {
65 return MBEDTLS_ERR_DHM_BAD_INPUT_DATA;
66 }
Paul Bakker5121ce52009-01-03 21:22:43 +000067
David Horstmannceeaeb92023-01-05 15:44:23 +000068 n = ((*p)[0] << 8) | (*p)[1];
Paul Bakker5121ce52009-01-03 21:22:43 +000069 (*p) += 2;
70
David Horstmannceeaeb92023-01-05 15:44:23 +000071 if ((int) (end - *p) < n) {
72 return MBEDTLS_ERR_DHM_BAD_INPUT_DATA;
73 }
Paul Bakker5121ce52009-01-03 21:22:43 +000074
David Horstmannceeaeb92023-01-05 15:44:23 +000075 if ((ret = mbedtls_mpi_read_binary(X, *p, n)) != 0) {
76 return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_DHM_READ_PARAMS_FAILED, ret);
77 }
Paul Bakker5121ce52009-01-03 21:22:43 +000078
79 (*p) += n;
80
David Horstmannceeaeb92023-01-05 15:44:23 +000081 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +000082}
83
84/*
Paul Bakkeraec37cb2012-04-26 18:59:59 +000085 * Verify sanity of parameter with regards to P
Paul Bakker345a6fe2011-02-28 21:20:02 +000086 *
Paul Bakkeraec37cb2012-04-26 18:59:59 +000087 * Parameter should be: 2 <= public_param <= P - 2
Paul Bakker345a6fe2011-02-28 21:20:02 +000088 *
Janos Follathaa325d72017-09-20 15:33:24 +010089 * This means that we need to return an error if
Janos Follath1ad1c6d2017-09-21 09:02:11 +010090 * public_param < 2 or public_param > P-2
Janos Follathaa325d72017-09-20 15:33:24 +010091 *
Paul Bakker345a6fe2011-02-28 21:20:02 +000092 * For more information on the attack, see:
93 * http://www.cl.cam.ac.uk/~rja14/Papers/psandqs.pdf
94 * http://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2005-2643
Paul Bakkerc47840e2011-02-20 16:37:30 +000095 */
David Horstmannceeaeb92023-01-05 15:44:23 +000096static int dhm_check_range(const mbedtls_mpi *param, const mbedtls_mpi *P)
Paul Bakkerc47840e2011-02-20 16:37:30 +000097{
Gilles Peskine58df4c92021-03-31 22:56:43 +020098 mbedtls_mpi U;
Janos Follathaa325d72017-09-20 15:33:24 +010099 int ret = 0;
Paul Bakkerc47840e2011-02-20 16:37:30 +0000100
David Horstmannceeaeb92023-01-05 15:44:23 +0000101 mbedtls_mpi_init(&U);
Paul Bakker3d8fb632014-04-17 12:42:41 +0200102
David Horstmannceeaeb92023-01-05 15:44:23 +0000103 MBEDTLS_MPI_CHK(mbedtls_mpi_sub_int(&U, P, 2));
Paul Bakkerc47840e2011-02-20 16:37:30 +0000104
David Horstmannceeaeb92023-01-05 15:44:23 +0000105 if (mbedtls_mpi_cmp_int(param, 2) < 0 ||
106 mbedtls_mpi_cmp_mpi(param, &U) > 0) {
Janos Follathaa325d72017-09-20 15:33:24 +0100107 ret = MBEDTLS_ERR_DHM_BAD_INPUT_DATA;
Paul Bakkerc47840e2011-02-20 16:37:30 +0000108 }
109
Paul Bakker3d8fb632014-04-17 12:42:41 +0200110cleanup:
David Horstmannceeaeb92023-01-05 15:44:23 +0000111 mbedtls_mpi_free(&U);
112 return ret;
Paul Bakkerc47840e2011-02-20 16:37:30 +0000113}
114
David Horstmannceeaeb92023-01-05 15:44:23 +0000115void mbedtls_dhm_init(mbedtls_dhm_context *ctx)
Paul Bakker8f870b02014-06-20 13:32:38 +0200116{
David Horstmannceeaeb92023-01-05 15:44:23 +0000117 DHM_VALIDATE(ctx != NULL);
118 memset(ctx, 0, sizeof(mbedtls_dhm_context));
Paul Bakker8f870b02014-06-20 13:32:38 +0200119}
120
Paul Bakkerc47840e2011-02-20 16:37:30 +0000121/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000122 * Parse the ServerKeyExchange parameters
123 */
David Horstmannceeaeb92023-01-05 15:44:23 +0000124int mbedtls_dhm_read_params(mbedtls_dhm_context *ctx,
125 unsigned char **p,
126 const unsigned char *end)
Paul Bakker5121ce52009-01-03 21:22:43 +0000127{
Janos Follath24eed8d2019-11-22 13:21:35 +0000128 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
David Horstmannceeaeb92023-01-05 15:44:23 +0000129 DHM_VALIDATE_RET(ctx != NULL);
130 DHM_VALIDATE_RET(p != NULL && *p != NULL);
131 DHM_VALIDATE_RET(end != NULL);
Paul Bakker5121ce52009-01-03 21:22:43 +0000132
David Horstmannceeaeb92023-01-05 15:44:23 +0000133 if ((ret = dhm_read_bignum(&ctx->P, p, end)) != 0 ||
134 (ret = dhm_read_bignum(&ctx->G, p, end)) != 0 ||
135 (ret = dhm_read_bignum(&ctx->GY, p, end)) != 0) {
136 return ret;
137 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000138
David Horstmannceeaeb92023-01-05 15:44:23 +0000139 if ((ret = dhm_check_range(&ctx->GY, &ctx->P)) != 0) {
140 return ret;
141 }
Paul Bakker345a6fe2011-02-28 21:20:02 +0000142
David Horstmannceeaeb92023-01-05 15:44:23 +0000143 ctx->len = mbedtls_mpi_size(&ctx->P);
Paul Bakker5121ce52009-01-03 21:22:43 +0000144
David Horstmannceeaeb92023-01-05 15:44:23 +0000145 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000146}
147
Gilles Peskine87fdb1f2021-03-31 22:48:14 +0200148/*
Gilles Peskine16e36682021-03-31 23:04:50 +0200149 * Pick a random R in the range [2, M-2] for blinding or key generation.
Gilles Peskine87fdb1f2021-03-31 22:48:14 +0200150 */
David Horstmannceeaeb92023-01-05 15:44:23 +0000151static int dhm_random_below(mbedtls_mpi *R, const mbedtls_mpi *M,
152 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng)
Gilles Peskine87fdb1f2021-03-31 22:48:14 +0200153{
Gilles Peskine16e36682021-03-31 23:04:50 +0200154 int ret;
Gilles Peskine87fdb1f2021-03-31 22:48:14 +0200155
David Horstmannceeaeb92023-01-05 15:44:23 +0000156 MBEDTLS_MPI_CHK(mbedtls_mpi_random(R, 3, M, f_rng, p_rng));
157 MBEDTLS_MPI_CHK(mbedtls_mpi_sub_int(R, R, 1));
Gilles Peskine87fdb1f2021-03-31 22:48:14 +0200158
159cleanup:
David Horstmannceeaeb92023-01-05 15:44:23 +0000160 return ret;
Gilles Peskine87fdb1f2021-03-31 22:48:14 +0200161}
162
David Horstmannceeaeb92023-01-05 15:44:23 +0000163static int dhm_make_common(mbedtls_dhm_context *ctx, int x_size,
164 int (*f_rng)(void *, unsigned char *, size_t),
165 void *p_rng)
Paul Bakker5121ce52009-01-03 21:22:43 +0000166{
Gilles Peskine87fdb1f2021-03-31 22:48:14 +0200167 int ret = 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000168
David Horstmannceeaeb92023-01-05 15:44:23 +0000169 if (mbedtls_mpi_cmp_int(&ctx->P, 0) == 0) {
170 return MBEDTLS_ERR_DHM_BAD_INPUT_DATA;
Paul Bakkeraec37cb2012-04-26 18:59:59 +0000171 }
David Horstmannceeaeb92023-01-05 15:44:23 +0000172 if (x_size < 0) {
173 return MBEDTLS_ERR_DHM_BAD_INPUT_DATA;
174 }
175
176 if ((unsigned) x_size < mbedtls_mpi_size(&ctx->P)) {
177 MBEDTLS_MPI_CHK(mbedtls_mpi_fill_random(&ctx->X, x_size, f_rng, p_rng));
178 } else {
Gilles Peskine87fdb1f2021-03-31 22:48:14 +0200179 /* Generate X as large as possible ( <= P - 2 ) */
David Horstmannceeaeb92023-01-05 15:44:23 +0000180 ret = dhm_random_below(&ctx->X, &ctx->P, f_rng, p_rng);
181 if (ret == MBEDTLS_ERR_MPI_NOT_ACCEPTABLE) {
182 return MBEDTLS_ERR_DHM_MAKE_PARAMS_FAILED;
183 }
184 if (ret != 0) {
185 return ret;
186 }
Gilles Peskine87fdb1f2021-03-31 22:48:14 +0200187 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000188
Paul Bakkerff7fe672010-07-18 09:45:05 +0000189 /*
190 * Calculate GX = G^X mod P
191 */
David Horstmannceeaeb92023-01-05 15:44:23 +0000192 MBEDTLS_MPI_CHK(mbedtls_mpi_exp_mod(&ctx->GX, &ctx->G, &ctx->X,
193 &ctx->P, &ctx->RP));
Paul Bakker5121ce52009-01-03 21:22:43 +0000194
David Horstmannceeaeb92023-01-05 15:44:23 +0000195 if ((ret = dhm_check_range(&ctx->GX, &ctx->P)) != 0) {
196 return ret;
197 }
Paul Bakkerc47840e2011-02-20 16:37:30 +0000198
Gilles Peskine0853bb22021-03-31 22:35:13 +0200199cleanup:
David Horstmannceeaeb92023-01-05 15:44:23 +0000200 return ret;
Gilles Peskine0853bb22021-03-31 22:35:13 +0200201}
202
203/*
204 * Setup and write the ServerKeyExchange parameters
205 */
David Horstmannceeaeb92023-01-05 15:44:23 +0000206int mbedtls_dhm_make_params(mbedtls_dhm_context *ctx, int x_size,
207 unsigned char *output, size_t *olen,
208 int (*f_rng)(void *, unsigned char *, size_t),
209 void *p_rng)
Gilles Peskine0853bb22021-03-31 22:35:13 +0200210{
211 int ret;
212 size_t n1, n2, n3;
213 unsigned char *p;
David Horstmannceeaeb92023-01-05 15:44:23 +0000214 DHM_VALIDATE_RET(ctx != NULL);
215 DHM_VALIDATE_RET(output != NULL);
216 DHM_VALIDATE_RET(olen != NULL);
217 DHM_VALIDATE_RET(f_rng != NULL);
Gilles Peskine0853bb22021-03-31 22:35:13 +0200218
David Horstmannceeaeb92023-01-05 15:44:23 +0000219 ret = dhm_make_common(ctx, x_size, f_rng, p_rng);
220 if (ret != 0) {
Gilles Peskine0853bb22021-03-31 22:35:13 +0200221 goto cleanup;
David Horstmannceeaeb92023-01-05 15:44:23 +0000222 }
Gilles Peskine0853bb22021-03-31 22:35:13 +0200223
Paul Bakker5121ce52009-01-03 21:22:43 +0000224 /*
Gilles Peskine104eb822021-04-13 22:10:24 +0200225 * Export P, G, GX. RFC 5246 §4.4 states that "leading zero octets are
226 * not required". We omit leading zeros for compactness.
Paul Bakker5121ce52009-01-03 21:22:43 +0000227 */
David Horstmannceeaeb92023-01-05 15:44:23 +0000228#define DHM_MPI_EXPORT(X, n) \
Hanno Beckere71ad122017-09-28 10:32:25 +0100229 do { \
David Horstmannceeaeb92023-01-05 15:44:23 +0000230 MBEDTLS_MPI_CHK(mbedtls_mpi_write_binary((X), \
231 p + 2, \
232 (n))); \
233 *p++ = MBEDTLS_BYTE_1(n); \
234 *p++ = MBEDTLS_BYTE_0(n); \
235 p += (n); \
236 } while (0)
Paul Bakker5121ce52009-01-03 21:22:43 +0000237
David Horstmannceeaeb92023-01-05 15:44:23 +0000238 n1 = mbedtls_mpi_size(&ctx->P);
239 n2 = mbedtls_mpi_size(&ctx->G);
240 n3 = mbedtls_mpi_size(&ctx->GX);
Paul Bakker5121ce52009-01-03 21:22:43 +0000241
242 p = output;
David Horstmannceeaeb92023-01-05 15:44:23 +0000243 DHM_MPI_EXPORT(&ctx->P, n1);
244 DHM_MPI_EXPORT(&ctx->G, n2);
245 DHM_MPI_EXPORT(&ctx->GX, n3);
Paul Bakker5121ce52009-01-03 21:22:43 +0000246
Hanno Beckere71ad122017-09-28 10:32:25 +0100247 *olen = p - output;
Paul Bakker5121ce52009-01-03 21:22:43 +0000248
249 ctx->len = n1;
250
251cleanup:
David Horstmannceeaeb92023-01-05 15:44:23 +0000252 if (ret != 0 && ret > -128) {
253 ret = MBEDTLS_ERROR_ADD(MBEDTLS_ERR_DHM_MAKE_PARAMS_FAILED, ret);
254 }
255 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +0000256}
257
258/*
Hanno Becker8880e752017-10-04 13:15:08 +0100259 * Set prime modulus and generator
260 */
David Horstmannceeaeb92023-01-05 15:44:23 +0000261int mbedtls_dhm_set_group(mbedtls_dhm_context *ctx,
262 const mbedtls_mpi *P,
263 const mbedtls_mpi *G)
Hanno Becker8880e752017-10-04 13:15:08 +0100264{
Janos Follath24eed8d2019-11-22 13:21:35 +0000265 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
David Horstmannceeaeb92023-01-05 15:44:23 +0000266 DHM_VALIDATE_RET(ctx != NULL);
267 DHM_VALIDATE_RET(P != NULL);
268 DHM_VALIDATE_RET(G != NULL);
Hanno Becker8880e752017-10-04 13:15:08 +0100269
David Horstmannceeaeb92023-01-05 15:44:23 +0000270 if ((ret = mbedtls_mpi_copy(&ctx->P, P)) != 0 ||
271 (ret = mbedtls_mpi_copy(&ctx->G, G)) != 0) {
272 return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_DHM_SET_GROUP_FAILED, ret);
Hanno Becker8880e752017-10-04 13:15:08 +0100273 }
274
David Horstmannceeaeb92023-01-05 15:44:23 +0000275 ctx->len = mbedtls_mpi_size(&ctx->P);
276 return 0;
Hanno Becker8880e752017-10-04 13:15:08 +0100277}
278
279/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000280 * Import the peer's public value G^Y
281 */
David Horstmannceeaeb92023-01-05 15:44:23 +0000282int mbedtls_dhm_read_public(mbedtls_dhm_context *ctx,
283 const unsigned char *input, size_t ilen)
Paul Bakker5121ce52009-01-03 21:22:43 +0000284{
Janos Follath24eed8d2019-11-22 13:21:35 +0000285 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
David Horstmannceeaeb92023-01-05 15:44:23 +0000286 DHM_VALIDATE_RET(ctx != NULL);
287 DHM_VALIDATE_RET(input != NULL);
Paul Bakker5121ce52009-01-03 21:22:43 +0000288
David Horstmannceeaeb92023-01-05 15:44:23 +0000289 if (ilen < 1 || ilen > ctx->len) {
290 return MBEDTLS_ERR_DHM_BAD_INPUT_DATA;
291 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000292
David Horstmannceeaeb92023-01-05 15:44:23 +0000293 if ((ret = mbedtls_mpi_read_binary(&ctx->GY, input, ilen)) != 0) {
294 return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_DHM_READ_PUBLIC_FAILED, ret);
295 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000296
David Horstmannceeaeb92023-01-05 15:44:23 +0000297 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000298}
299
300/*
301 * Create own private value X and export G^X
302 */
David Horstmannceeaeb92023-01-05 15:44:23 +0000303int mbedtls_dhm_make_public(mbedtls_dhm_context *ctx, int x_size,
304 unsigned char *output, size_t olen,
305 int (*f_rng)(void *, unsigned char *, size_t),
306 void *p_rng)
Paul Bakker5121ce52009-01-03 21:22:43 +0000307{
Gilles Peskine0853bb22021-03-31 22:35:13 +0200308 int ret;
David Horstmannceeaeb92023-01-05 15:44:23 +0000309 DHM_VALIDATE_RET(ctx != NULL);
310 DHM_VALIDATE_RET(output != NULL);
311 DHM_VALIDATE_RET(f_rng != NULL);
Paul Bakker5121ce52009-01-03 21:22:43 +0000312
David Horstmannceeaeb92023-01-05 15:44:23 +0000313 if (olen < 1 || olen > ctx->len) {
314 return MBEDTLS_ERR_DHM_BAD_INPUT_DATA;
315 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000316
David Horstmannceeaeb92023-01-05 15:44:23 +0000317 ret = dhm_make_common(ctx, x_size, f_rng, p_rng);
318 if (ret == MBEDTLS_ERR_DHM_MAKE_PARAMS_FAILED) {
319 return MBEDTLS_ERR_DHM_MAKE_PUBLIC_FAILED;
320 }
321 if (ret != 0) {
Gilles Peskine0853bb22021-03-31 22:35:13 +0200322 goto cleanup;
David Horstmannceeaeb92023-01-05 15:44:23 +0000323 }
Paul Bakkerc47840e2011-02-20 16:37:30 +0000324
David Horstmannceeaeb92023-01-05 15:44:23 +0000325 MBEDTLS_MPI_CHK(mbedtls_mpi_write_binary(&ctx->GX, output, olen));
Paul Bakker5121ce52009-01-03 21:22:43 +0000326
327cleanup:
David Horstmannceeaeb92023-01-05 15:44:23 +0000328 if (ret != 0 && ret > -128) {
329 ret = MBEDTLS_ERROR_ADD(MBEDTLS_ERR_DHM_MAKE_PUBLIC_FAILED, ret);
330 }
331 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +0000332}
333
Manuel Pégourié-Gonnard9f58c4b2020-06-25 12:34:58 +0200334
335/*
Manuel Pégourié-Gonnard143b5022013-09-04 16:29:59 +0200336 * Use the blinding method and optimisation suggested in section 10 of:
337 * KOCHER, Paul C. Timing attacks on implementations of Diffie-Hellman, RSA,
Manuel Pégourié-Gonnard998930a2015-04-03 13:48:06 +0200338 * DSS, and other systems. In : Advances in Cryptology-CRYPTO'96. Springer
Manuel Pégourié-Gonnard143b5022013-09-04 16:29:59 +0200339 * Berlin Heidelberg, 1996. p. 104-113.
340 */
David Horstmannceeaeb92023-01-05 15:44:23 +0000341static int dhm_update_blinding(mbedtls_dhm_context *ctx,
342 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng)
Manuel Pégourié-Gonnard143b5022013-09-04 16:29:59 +0200343{
Manuel Pégourié-Gonnard9f58c4b2020-06-25 12:34:58 +0200344 int ret;
Manuel Pégourié-Gonnardaf721672020-06-25 12:47:22 +0200345 mbedtls_mpi R;
346
David Horstmannceeaeb92023-01-05 15:44:23 +0000347 mbedtls_mpi_init(&R);
Manuel Pégourié-Gonnard143b5022013-09-04 16:29:59 +0200348
349 /*
Manuel Pégourié-Gonnard15d5de12013-09-17 11:34:11 +0200350 * Don't use any blinding the first time a particular X is used,
351 * but remember it to use blinding next time.
Manuel Pégourié-Gonnard143b5022013-09-04 16:29:59 +0200352 */
David Horstmannceeaeb92023-01-05 15:44:23 +0000353 if (mbedtls_mpi_cmp_mpi(&ctx->X, &ctx->pX) != 0) {
354 MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&ctx->pX, &ctx->X));
355 MBEDTLS_MPI_CHK(mbedtls_mpi_lset(&ctx->Vi, 1));
356 MBEDTLS_MPI_CHK(mbedtls_mpi_lset(&ctx->Vf, 1));
Manuel Pégourié-Gonnarded8a02b2013-09-04 16:39:03 +0200357
David Horstmannceeaeb92023-01-05 15:44:23 +0000358 return 0;
Manuel Pégourié-Gonnard143b5022013-09-04 16:29:59 +0200359 }
360
361 /*
Manuel Pégourié-Gonnard15d5de12013-09-17 11:34:11 +0200362 * Ok, we need blinding. Can we re-use existing values?
363 * If yes, just update them by squaring them.
Manuel Pégourié-Gonnard143b5022013-09-04 16:29:59 +0200364 */
David Horstmannceeaeb92023-01-05 15:44:23 +0000365 if (mbedtls_mpi_cmp_int(&ctx->Vi, 1) != 0) {
366 MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(&ctx->Vi, &ctx->Vi, &ctx->Vi));
367 MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(&ctx->Vi, &ctx->Vi, &ctx->P));
Manuel Pégourié-Gonnard15d5de12013-09-17 11:34:11 +0200368
David Horstmannceeaeb92023-01-05 15:44:23 +0000369 MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(&ctx->Vf, &ctx->Vf, &ctx->Vf));
370 MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(&ctx->Vf, &ctx->Vf, &ctx->P));
Manuel Pégourié-Gonnard15d5de12013-09-17 11:34:11 +0200371
David Horstmannceeaeb92023-01-05 15:44:23 +0000372 return 0;
Manuel Pégourié-Gonnard15d5de12013-09-17 11:34:11 +0200373 }
374
375 /*
376 * We need to generate blinding values from scratch
377 */
378
Gilles Peskineb4e815f2021-03-31 22:50:57 +0200379 /* Vi = random( 2, P-2 ) */
David Horstmannceeaeb92023-01-05 15:44:23 +0000380 MBEDTLS_MPI_CHK(dhm_random_below(&ctx->Vi, &ctx->P, f_rng, p_rng));
Manuel Pégourié-Gonnard15d5de12013-09-17 11:34:11 +0200381
Manuel Pégourié-Gonnardaf721672020-06-25 12:47:22 +0200382 /* Vf = Vi^-X mod P
383 * First compute Vi^-1 = R * (R Vi)^-1, (avoiding leaks from inv_mod),
384 * then elevate to the Xth power. */
David Horstmannceeaeb92023-01-05 15:44:23 +0000385 MBEDTLS_MPI_CHK(dhm_random_below(&R, &ctx->P, f_rng, p_rng));
386 MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(&ctx->Vf, &ctx->Vi, &R));
387 MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(&ctx->Vf, &ctx->Vf, &ctx->P));
388 MBEDTLS_MPI_CHK(mbedtls_mpi_inv_mod(&ctx->Vf, &ctx->Vf, &ctx->P));
389 MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(&ctx->Vf, &ctx->Vf, &R));
390 MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(&ctx->Vf, &ctx->Vf, &ctx->P));
Manuel Pégourié-Gonnard15d5de12013-09-17 11:34:11 +0200391
David Horstmannceeaeb92023-01-05 15:44:23 +0000392 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 +0200393
Manuel Pégourié-Gonnard143b5022013-09-04 16:29:59 +0200394cleanup:
David Horstmannceeaeb92023-01-05 15:44:23 +0000395 mbedtls_mpi_free(&R);
Manuel Pégourié-Gonnardaf721672020-06-25 12:47:22 +0200396
David Horstmannceeaeb92023-01-05 15:44:23 +0000397 return ret;
Manuel Pégourié-Gonnard143b5022013-09-04 16:29:59 +0200398}
399
400/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000401 * Derive and export the shared secret (G^Y)^X mod P
402 */
David Horstmannceeaeb92023-01-05 15:44:23 +0000403int mbedtls_dhm_calc_secret(mbedtls_dhm_context *ctx,
404 unsigned char *output, size_t output_size, size_t *olen,
405 int (*f_rng)(void *, unsigned char *, size_t),
406 void *p_rng)
Paul Bakker5121ce52009-01-03 21:22:43 +0000407{
Janos Follath24eed8d2019-11-22 13:21:35 +0000408 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200409 mbedtls_mpi GYb;
David Horstmannceeaeb92023-01-05 15:44:23 +0000410 DHM_VALIDATE_RET(ctx != NULL);
411 DHM_VALIDATE_RET(output != NULL);
412 DHM_VALIDATE_RET(olen != NULL);
Manuel Pégourié-Gonnard2d627642013-09-04 14:22:07 +0200413
David Horstmannceeaeb92023-01-05 15:44:23 +0000414 if (output_size < ctx->len) {
415 return MBEDTLS_ERR_DHM_BAD_INPUT_DATA;
416 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000417
David Horstmannceeaeb92023-01-05 15:44:23 +0000418 if ((ret = dhm_check_range(&ctx->GY, &ctx->P)) != 0) {
419 return ret;
420 }
Paul Bakkerc47840e2011-02-20 16:37:30 +0000421
David Horstmannceeaeb92023-01-05 15:44:23 +0000422 mbedtls_mpi_init(&GYb);
Manuel Pégourié-Gonnard143b5022013-09-04 16:29:59 +0200423
424 /* Blind peer's value */
David Horstmannceeaeb92023-01-05 15:44:23 +0000425 if (f_rng != NULL) {
426 MBEDTLS_MPI_CHK(dhm_update_blinding(ctx, f_rng, p_rng));
427 MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(&GYb, &ctx->GY, &ctx->Vi));
428 MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(&GYb, &GYb, &ctx->P));
429 } else {
430 MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&GYb, &ctx->GY));
Manuel Pégourié-Gonnard143b5022013-09-04 16:29:59 +0200431 }
Manuel Pégourié-Gonnard143b5022013-09-04 16:29:59 +0200432
433 /* Do modular exponentiation */
David Horstmannceeaeb92023-01-05 15:44:23 +0000434 MBEDTLS_MPI_CHK(mbedtls_mpi_exp_mod(&ctx->K, &GYb, &ctx->X,
435 &ctx->P, &ctx->RP));
Manuel Pégourié-Gonnard143b5022013-09-04 16:29:59 +0200436
437 /* Unblind secret value */
David Horstmannceeaeb92023-01-05 15:44:23 +0000438 if (f_rng != NULL) {
439 MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(&ctx->K, &ctx->K, &ctx->Vf));
440 MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(&ctx->K, &ctx->K, &ctx->P));
Manuel Pégourié-Gonnard143b5022013-09-04 16:29:59 +0200441 }
442
Gilles Peskine104eb822021-04-13 22:10:24 +0200443 /* Output the secret without any leading zero byte. This is mandatory
444 * for TLS per RFC 5246 §8.1.2. */
David Horstmannceeaeb92023-01-05 15:44:23 +0000445 *olen = mbedtls_mpi_size(&ctx->K);
446 MBEDTLS_MPI_CHK(mbedtls_mpi_write_binary(&ctx->K, output, *olen));
Paul Bakker5121ce52009-01-03 21:22:43 +0000447
448cleanup:
David Horstmannceeaeb92023-01-05 15:44:23 +0000449 mbedtls_mpi_free(&GYb);
Paul Bakker5121ce52009-01-03 21:22:43 +0000450
David Horstmannceeaeb92023-01-05 15:44:23 +0000451 if (ret != 0) {
452 return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_DHM_CALC_SECRET_FAILED, ret);
453 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000454
David Horstmannceeaeb92023-01-05 15:44:23 +0000455 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000456}
457
458/*
459 * Free the components of a DHM key
460 */
David Horstmannceeaeb92023-01-05 15:44:23 +0000461void mbedtls_dhm_free(mbedtls_dhm_context *ctx)
Paul Bakker5121ce52009-01-03 21:22:43 +0000462{
David Horstmannceeaeb92023-01-05 15:44:23 +0000463 if (ctx == NULL) {
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500464 return;
David Horstmannceeaeb92023-01-05 15:44:23 +0000465 }
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500466
David Horstmannceeaeb92023-01-05 15:44:23 +0000467 mbedtls_mpi_free(&ctx->pX);
468 mbedtls_mpi_free(&ctx->Vf);
469 mbedtls_mpi_free(&ctx->Vi);
470 mbedtls_mpi_free(&ctx->RP);
471 mbedtls_mpi_free(&ctx->K);
472 mbedtls_mpi_free(&ctx->GY);
473 mbedtls_mpi_free(&ctx->GX);
474 mbedtls_mpi_free(&ctx->X);
475 mbedtls_mpi_free(&ctx->G);
476 mbedtls_mpi_free(&ctx->P);
Manuel Pégourié-Gonnardb72b4ed2013-09-13 13:55:26 +0200477
David Horstmannceeaeb92023-01-05 15:44:23 +0000478 mbedtls_platform_zeroize(ctx, sizeof(mbedtls_dhm_context));
Paul Bakker5121ce52009-01-03 21:22:43 +0000479}
480
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200481#if defined(MBEDTLS_ASN1_PARSE_C)
Paul Bakker40ce79f2013-09-15 17:43:54 +0200482/*
483 * Parse DHM parameters
484 */
David Horstmannceeaeb92023-01-05 15:44:23 +0000485int mbedtls_dhm_parse_dhm(mbedtls_dhm_context *dhm, const unsigned char *dhmin,
486 size_t dhminlen)
Paul Bakker40ce79f2013-09-15 17:43:54 +0200487{
Janos Follath24eed8d2019-11-22 13:21:35 +0000488 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker40ce79f2013-09-15 17:43:54 +0200489 size_t len;
490 unsigned char *p, *end;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200491#if defined(MBEDTLS_PEM_PARSE_C)
492 mbedtls_pem_context pem;
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500493#endif /* MBEDTLS_PEM_PARSE_C */
Paul Bakker40ce79f2013-09-15 17:43:54 +0200494
David Horstmannceeaeb92023-01-05 15:44:23 +0000495 DHM_VALIDATE_RET(dhm != NULL);
496 DHM_VALIDATE_RET(dhmin != NULL);
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500497
498#if defined(MBEDTLS_PEM_PARSE_C)
David Horstmannceeaeb92023-01-05 15:44:23 +0000499 mbedtls_pem_init(&pem);
Paul Bakker40ce79f2013-09-15 17:43:54 +0200500
Manuel Pégourié-Gonnard43b37cb2015-05-12 11:20:10 +0200501 /* Avoid calling mbedtls_pem_read_buffer() on non-null-terminated string */
David Horstmannceeaeb92023-01-05 15:44:23 +0000502 if (dhminlen == 0 || dhmin[dhminlen - 1] != '\0') {
Manuel Pégourié-Gonnard43b37cb2015-05-12 11:20:10 +0200503 ret = MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT;
David Horstmannceeaeb92023-01-05 15:44:23 +0000504 } else {
505 ret = mbedtls_pem_read_buffer(&pem,
506 "-----BEGIN DH PARAMETERS-----",
507 "-----END DH PARAMETERS-----",
508 dhmin, NULL, 0, &dhminlen);
509 }
Paul Bakker40ce79f2013-09-15 17:43:54 +0200510
David Horstmannceeaeb92023-01-05 15:44:23 +0000511 if (ret == 0) {
Paul Bakker40ce79f2013-09-15 17:43:54 +0200512 /*
513 * Was PEM encoded
514 */
515 dhminlen = pem.buflen;
David Horstmannceeaeb92023-01-05 15:44:23 +0000516 } else if (ret != MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT) {
Paul Bakker40ce79f2013-09-15 17:43:54 +0200517 goto exit;
David Horstmannceeaeb92023-01-05 15:44:23 +0000518 }
Paul Bakker40ce79f2013-09-15 17:43:54 +0200519
David Horstmannceeaeb92023-01-05 15:44:23 +0000520 p = (ret == 0) ? pem.buf : (unsigned char *) dhmin;
Paul Bakker40ce79f2013-09-15 17:43:54 +0200521#else
522 p = (unsigned char *) dhmin;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200523#endif /* MBEDTLS_PEM_PARSE_C */
Paul Bakker40ce79f2013-09-15 17:43:54 +0200524 end = p + dhminlen;
525
526 /*
527 * DHParams ::= SEQUENCE {
Daniel Kahn Gillmor2ed81732015-04-03 13:09:24 -0400528 * prime INTEGER, -- P
529 * generator INTEGER, -- g
530 * privateValueLength INTEGER OPTIONAL
Paul Bakker40ce79f2013-09-15 17:43:54 +0200531 * }
532 */
David Horstmannceeaeb92023-01-05 15:44:23 +0000533 if ((ret = mbedtls_asn1_get_tag(&p, end, &len,
534 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) {
535 ret = MBEDTLS_ERROR_ADD(MBEDTLS_ERR_DHM_INVALID_FORMAT, ret);
Paul Bakker40ce79f2013-09-15 17:43:54 +0200536 goto exit;
537 }
538
539 end = p + len;
540
David Horstmannceeaeb92023-01-05 15:44:23 +0000541 if ((ret = mbedtls_asn1_get_mpi(&p, end, &dhm->P)) != 0 ||
542 (ret = mbedtls_asn1_get_mpi(&p, end, &dhm->G)) != 0) {
543 ret = MBEDTLS_ERROR_ADD(MBEDTLS_ERR_DHM_INVALID_FORMAT, ret);
Paul Bakker40ce79f2013-09-15 17:43:54 +0200544 goto exit;
545 }
546
David Horstmannceeaeb92023-01-05 15:44:23 +0000547 if (p != end) {
Manuel Pégourié-Gonnardde9b3632015-04-17 20:06:31 +0200548 /* This might be the optional privateValueLength.
549 * If so, we can cleanly discard it */
550 mbedtls_mpi rec;
David Horstmannceeaeb92023-01-05 15:44:23 +0000551 mbedtls_mpi_init(&rec);
552 ret = mbedtls_asn1_get_mpi(&p, end, &rec);
553 mbedtls_mpi_free(&rec);
554 if (ret != 0) {
555 ret = MBEDTLS_ERROR_ADD(MBEDTLS_ERR_DHM_INVALID_FORMAT, ret);
Daniel Kahn Gillmor2ed81732015-04-03 13:09:24 -0400556 goto exit;
557 }
David Horstmannceeaeb92023-01-05 15:44:23 +0000558 if (p != end) {
559 ret = MBEDTLS_ERROR_ADD(MBEDTLS_ERR_DHM_INVALID_FORMAT,
560 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
Daniel Kahn Gillmor2ed81732015-04-03 13:09:24 -0400561 goto exit;
562 }
Paul Bakker40ce79f2013-09-15 17:43:54 +0200563 }
564
565 ret = 0;
566
David Horstmannceeaeb92023-01-05 15:44:23 +0000567 dhm->len = mbedtls_mpi_size(&dhm->P);
Manuel Pégourié-Gonnard3fec2202014-03-29 16:42:38 +0100568
Paul Bakker40ce79f2013-09-15 17:43:54 +0200569exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200570#if defined(MBEDTLS_PEM_PARSE_C)
David Horstmannceeaeb92023-01-05 15:44:23 +0000571 mbedtls_pem_free(&pem);
Paul Bakker40ce79f2013-09-15 17:43:54 +0200572#endif
David Horstmannceeaeb92023-01-05 15:44:23 +0000573 if (ret != 0) {
574 mbedtls_dhm_free(dhm);
575 }
Paul Bakker40ce79f2013-09-15 17:43:54 +0200576
David Horstmannceeaeb92023-01-05 15:44:23 +0000577 return ret;
Paul Bakker40ce79f2013-09-15 17:43:54 +0200578}
579
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200580#if defined(MBEDTLS_FS_IO)
Paul Bakker40ce79f2013-09-15 17:43:54 +0200581/*
582 * Load all data from a file into a given buffer.
Manuel Pégourié-Gonnard43b37cb2015-05-12 11:20:10 +0200583 *
584 * The file is expected to contain either PEM or DER encoded data.
585 * A terminating null byte is always appended. It is included in the announced
586 * length only if the data looks like it is PEM encoded.
Paul Bakker40ce79f2013-09-15 17:43:54 +0200587 */
David Horstmannceeaeb92023-01-05 15:44:23 +0000588static int load_file(const char *path, unsigned char **buf, size_t *n)
Paul Bakker40ce79f2013-09-15 17:43:54 +0200589{
590 FILE *f;
591 long size;
592
David Horstmannceeaeb92023-01-05 15:44:23 +0000593 if ((f = fopen(path, "rb")) == NULL) {
594 return MBEDTLS_ERR_DHM_FILE_IO_ERROR;
Paul Bakker40ce79f2013-09-15 17:43:54 +0200595 }
David Horstmannceeaeb92023-01-05 15:44:23 +0000596
597 fseek(f, 0, SEEK_END);
598 if ((size = ftell(f)) == -1) {
599 fclose(f);
600 return MBEDTLS_ERR_DHM_FILE_IO_ERROR;
601 }
602 fseek(f, 0, SEEK_SET);
Paul Bakker40ce79f2013-09-15 17:43:54 +0200603
604 *n = (size_t) size;
605
David Horstmannceeaeb92023-01-05 15:44:23 +0000606 if (*n + 1 == 0 ||
607 (*buf = mbedtls_calloc(1, *n + 1)) == NULL) {
608 fclose(f);
609 return MBEDTLS_ERR_DHM_ALLOC_FAILED;
Paul Bakker40ce79f2013-09-15 17:43:54 +0200610 }
611
David Horstmannceeaeb92023-01-05 15:44:23 +0000612 if (fread(*buf, 1, *n, f) != *n) {
613 fclose(f);
Andres Amaya Garciabdbca7b2017-06-23 16:23:21 +0100614
David Horstmannceeaeb92023-01-05 15:44:23 +0000615 mbedtls_platform_zeroize(*buf, *n + 1);
616 mbedtls_free(*buf);
Andres Amaya Garciabdbca7b2017-06-23 16:23:21 +0100617
David Horstmannceeaeb92023-01-05 15:44:23 +0000618 return MBEDTLS_ERR_DHM_FILE_IO_ERROR;
Paul Bakker40ce79f2013-09-15 17:43:54 +0200619 }
620
David Horstmannceeaeb92023-01-05 15:44:23 +0000621 fclose(f);
Paul Bakker40ce79f2013-09-15 17:43:54 +0200622
623 (*buf)[*n] = '\0';
624
David Horstmannceeaeb92023-01-05 15:44:23 +0000625 if (strstr((const char *) *buf, "-----BEGIN ") != NULL) {
Manuel Pégourié-Gonnard43b37cb2015-05-12 11:20:10 +0200626 ++*n;
David Horstmannceeaeb92023-01-05 15:44:23 +0000627 }
Manuel Pégourié-Gonnard43b37cb2015-05-12 11:20:10 +0200628
David Horstmannceeaeb92023-01-05 15:44:23 +0000629 return 0;
Paul Bakker40ce79f2013-09-15 17:43:54 +0200630}
631
632/*
633 * Load and parse DHM parameters
634 */
David Horstmannceeaeb92023-01-05 15:44:23 +0000635int mbedtls_dhm_parse_dhmfile(mbedtls_dhm_context *dhm, const char *path)
Paul Bakker40ce79f2013-09-15 17:43:54 +0200636{
Janos Follath24eed8d2019-11-22 13:21:35 +0000637 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker40ce79f2013-09-15 17:43:54 +0200638 size_t n;
639 unsigned char *buf;
David Horstmannceeaeb92023-01-05 15:44:23 +0000640 DHM_VALIDATE_RET(dhm != NULL);
641 DHM_VALIDATE_RET(path != NULL);
Paul Bakker40ce79f2013-09-15 17:43:54 +0200642
David Horstmannceeaeb92023-01-05 15:44:23 +0000643 if ((ret = load_file(path, &buf, &n)) != 0) {
644 return ret;
645 }
Paul Bakker40ce79f2013-09-15 17:43:54 +0200646
David Horstmannceeaeb92023-01-05 15:44:23 +0000647 ret = mbedtls_dhm_parse_dhm(dhm, buf, n);
Paul Bakker40ce79f2013-09-15 17:43:54 +0200648
David Horstmannceeaeb92023-01-05 15:44:23 +0000649 mbedtls_platform_zeroize(buf, n);
650 mbedtls_free(buf);
Paul Bakker40ce79f2013-09-15 17:43:54 +0200651
David Horstmannceeaeb92023-01-05 15:44:23 +0000652 return ret;
Paul Bakker40ce79f2013-09-15 17:43:54 +0200653}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200654#endif /* MBEDTLS_FS_IO */
655#endif /* MBEDTLS_ASN1_PARSE_C */
nirekh0149762fa2017-12-25 06:46:48 +0000656#endif /* MBEDTLS_DHM_ALT */
Paul Bakker40ce79f2013-09-15 17:43:54 +0200657
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200658#if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +0000659
Hanno Becker8b0f9e62019-05-31 17:28:59 +0100660#if defined(MBEDTLS_PEM_PARSE_C)
Manuel Pégourié-Gonnard53585ee2015-06-25 08:52:25 +0200661static const char mbedtls_test_dhm_params[] =
David Horstmannceeaeb92023-01-05 15:44:23 +0000662 "-----BEGIN DH PARAMETERS-----\r\n"
663 "MIGHAoGBAJ419DBEOgmQTzo5qXl5fQcN9TN455wkOL7052HzxxRVMyhYmwQcgJvh\r\n"
664 "1sa18fyfR9OiVEMYglOpkqVoGLN7qd5aQNNi5W7/C+VBdHTBJcGZJyyP5B3qcz32\r\n"
665 "9mLJKudlVudV0Qxk5qUJaPZ/xupz0NyoVpviuiBOI1gNi8ovSXWzAgEC\r\n"
666 "-----END DH PARAMETERS-----\r\n";
Hanno Becker8b0f9e62019-05-31 17:28:59 +0100667#else /* MBEDTLS_PEM_PARSE_C */
668static const char mbedtls_test_dhm_params[] = {
David Horstmannceeaeb92023-01-05 15:44:23 +0000669 0x30, 0x81, 0x87, 0x02, 0x81, 0x81, 0x00, 0x9e, 0x35, 0xf4, 0x30, 0x44,
670 0x3a, 0x09, 0x90, 0x4f, 0x3a, 0x39, 0xa9, 0x79, 0x79, 0x7d, 0x07, 0x0d,
671 0xf5, 0x33, 0x78, 0xe7, 0x9c, 0x24, 0x38, 0xbe, 0xf4, 0xe7, 0x61, 0xf3,
672 0xc7, 0x14, 0x55, 0x33, 0x28, 0x58, 0x9b, 0x04, 0x1c, 0x80, 0x9b, 0xe1,
673 0xd6, 0xc6, 0xb5, 0xf1, 0xfc, 0x9f, 0x47, 0xd3, 0xa2, 0x54, 0x43, 0x18,
674 0x82, 0x53, 0xa9, 0x92, 0xa5, 0x68, 0x18, 0xb3, 0x7b, 0xa9, 0xde, 0x5a,
675 0x40, 0xd3, 0x62, 0xe5, 0x6e, 0xff, 0x0b, 0xe5, 0x41, 0x74, 0x74, 0xc1,
676 0x25, 0xc1, 0x99, 0x27, 0x2c, 0x8f, 0xe4, 0x1d, 0xea, 0x73, 0x3d, 0xf6,
677 0xf6, 0x62, 0xc9, 0x2a, 0xe7, 0x65, 0x56, 0xe7, 0x55, 0xd1, 0x0c, 0x64,
678 0xe6, 0xa5, 0x09, 0x68, 0xf6, 0x7f, 0xc6, 0xea, 0x73, 0xd0, 0xdc, 0xa8,
679 0x56, 0x9b, 0xe2, 0xba, 0x20, 0x4e, 0x23, 0x58, 0x0d, 0x8b, 0xca, 0x2f,
680 0x49, 0x75, 0xb3, 0x02, 0x01, 0x02
681};
Hanno Becker8b0f9e62019-05-31 17:28:59 +0100682#endif /* MBEDTLS_PEM_PARSE_C */
Manuel Pégourié-Gonnard53585ee2015-06-25 08:52:25 +0200683
David Horstmannceeaeb92023-01-05 15:44:23 +0000684static const size_t mbedtls_test_dhm_params_len = sizeof(mbedtls_test_dhm_params);
Paul Bakker40ce79f2013-09-15 17:43:54 +0200685
Paul Bakker5121ce52009-01-03 21:22:43 +0000686/*
687 * Checkup routine
688 */
David Horstmannceeaeb92023-01-05 15:44:23 +0000689int mbedtls_dhm_self_test(int verbose)
Paul Bakker5121ce52009-01-03 21:22:43 +0000690{
Janos Follath24eed8d2019-11-22 13:21:35 +0000691 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200692 mbedtls_dhm_context dhm;
Paul Bakker40ce79f2013-09-15 17:43:54 +0200693
David Horstmannceeaeb92023-01-05 15:44:23 +0000694 mbedtls_dhm_init(&dhm);
Paul Bakker8f870b02014-06-20 13:32:38 +0200695
David Horstmannceeaeb92023-01-05 15:44:23 +0000696 if (verbose != 0) {
697 mbedtls_printf(" DHM parameter load: ");
698 }
Paul Bakker40ce79f2013-09-15 17:43:54 +0200699
David Horstmannceeaeb92023-01-05 15:44:23 +0000700 if ((ret = mbedtls_dhm_parse_dhm(&dhm,
701 (const unsigned char *) mbedtls_test_dhm_params,
702 mbedtls_test_dhm_params_len)) != 0) {
703 if (verbose != 0) {
704 mbedtls_printf("failed\n");
705 }
Paul Bakker40ce79f2013-09-15 17:43:54 +0200706
Manuel Pégourié-Gonnardb196fc22014-07-09 16:53:29 +0200707 ret = 1;
Paul Bakker8f870b02014-06-20 13:32:38 +0200708 goto exit;
Paul Bakker40ce79f2013-09-15 17:43:54 +0200709 }
710
David Horstmannceeaeb92023-01-05 15:44:23 +0000711 if (verbose != 0) {
712 mbedtls_printf("passed\n\n");
713 }
Paul Bakker40ce79f2013-09-15 17:43:54 +0200714
Paul Bakker8f870b02014-06-20 13:32:38 +0200715exit:
David Horstmannceeaeb92023-01-05 15:44:23 +0000716 mbedtls_dhm_free(&dhm);
Paul Bakker40ce79f2013-09-15 17:43:54 +0200717
David Horstmannceeaeb92023-01-05 15:44:23 +0000718 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +0000719}
720
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200721#endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +0000722
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200723#endif /* MBEDTLS_DHM_C */