blob: 174137d54db8317ef2ce29f2b77cef01fa6cf444 [file] [log] [blame]
Paul Bakker5121ce52009-01-03 21:22:43 +00001/*
2 * Diffie-Hellman-Merkle key exchange
3 *
Bence Szépkúti1e148272020-08-07 13:07:28 +02004 * Copyright The Mbed TLS Contributors
Manuel Pégourié-Gonnard37ff1402015-09-04 14:21:07 +02005 * SPDX-License-Identifier: Apache-2.0
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License"); you may
8 * not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
15 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
Paul Bakker5121ce52009-01-03 21:22:43 +000018 */
19/*
Simon Butcherbdae02c2016-01-20 00:44:42 +000020 * The following sources were referenced in the design of this implementation
21 * of the Diffie-Hellman-Merkle algorithm:
Paul Bakker5121ce52009-01-03 21:22:43 +000022 *
Simon Butcherbdae02c2016-01-20 00:44:42 +000023 * [1] Handbook of Applied Cryptography - 1997, Chapter 12
24 * Menezes, van Oorschot and Vanstone
25 *
Paul Bakker5121ce52009-01-03 21:22:43 +000026 */
27
Gilles Peskinedb09ef62020-06-03 01:43:33 +020028#include "common.h"
Paul Bakker5121ce52009-01-03 21:22:43 +000029
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020030#if defined(MBEDTLS_DHM_C)
Paul Bakker5121ce52009-01-03 21:22:43 +000031
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000032#include "mbedtls/dhm.h"
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -050033#include "mbedtls/platform_util.h"
Janos Follath24eed8d2019-11-22 13:21:35 +000034#include "mbedtls/error.h"
Paul Bakker5121ce52009-01-03 21:22:43 +000035
Rich Evans00ab4702015-02-06 13:43:58 +000036#include <string.h>
37
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020038#if defined(MBEDTLS_PEM_PARSE_C)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000039#include "mbedtls/pem.h"
Paul Bakker40ce79f2013-09-15 17:43:54 +020040#endif
41
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020042#if defined(MBEDTLS_ASN1_PARSE_C)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000043#include "mbedtls/asn1.h"
Paul Bakker40ce79f2013-09-15 17:43:54 +020044#endif
45
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000046#include "mbedtls/platform.h"
Paul Bakker40ce79f2013-09-15 17:43:54 +020047
Reuven Levin1f35ca92017-12-07 10:09:32 +000048#if !defined(MBEDTLS_DHM_ALT)
Paul Bakker34617722014-06-13 17:20:13 +020049
Paul Bakker5121ce52009-01-03 21:22:43 +000050/*
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020051 * helper to validate the mbedtls_mpi size and import it
Paul Bakker5121ce52009-01-03 21:22:43 +000052 */
Gilles Peskine449bd832023-01-11 14:50:10 +010053static int dhm_read_bignum(mbedtls_mpi *X,
54 unsigned char **p,
55 const unsigned char *end)
Paul Bakker5121ce52009-01-03 21:22:43 +000056{
57 int ret, n;
58
Gilles Peskine449bd832023-01-11 14:50:10 +010059 if (end - *p < 2) {
60 return MBEDTLS_ERR_DHM_BAD_INPUT_DATA;
61 }
Paul Bakker5121ce52009-01-03 21:22:43 +000062
Gilles Peskine449bd832023-01-11 14:50:10 +010063 n = ((*p)[0] << 8) | (*p)[1];
Paul Bakker5121ce52009-01-03 21:22:43 +000064 (*p) += 2;
65
Gilles Peskine449bd832023-01-11 14:50:10 +010066 if ((int) (end - *p) < n) {
67 return MBEDTLS_ERR_DHM_BAD_INPUT_DATA;
68 }
Paul Bakker5121ce52009-01-03 21:22:43 +000069
Gilles Peskine449bd832023-01-11 14:50:10 +010070 if ((ret = mbedtls_mpi_read_binary(X, *p, n)) != 0) {
71 return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_DHM_READ_PARAMS_FAILED, ret);
72 }
Paul Bakker5121ce52009-01-03 21:22:43 +000073
74 (*p) += n;
75
Gilles Peskine449bd832023-01-11 14:50:10 +010076 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +000077}
78
79/*
Paul Bakkeraec37cb2012-04-26 18:59:59 +000080 * Verify sanity of parameter with regards to P
Paul Bakker345a6fe2011-02-28 21:20:02 +000081 *
Paul Bakkeraec37cb2012-04-26 18:59:59 +000082 * Parameter should be: 2 <= public_param <= P - 2
Paul Bakker345a6fe2011-02-28 21:20:02 +000083 *
Janos Follathaa325d72017-09-20 15:33:24 +010084 * This means that we need to return an error if
Janos Follath1ad1c6d2017-09-21 09:02:11 +010085 * public_param < 2 or public_param > P-2
Janos Follathaa325d72017-09-20 15:33:24 +010086 *
Paul Bakker345a6fe2011-02-28 21:20:02 +000087 * For more information on the attack, see:
88 * http://www.cl.cam.ac.uk/~rja14/Papers/psandqs.pdf
89 * http://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2005-2643
Paul Bakkerc47840e2011-02-20 16:37:30 +000090 */
Gilles Peskine449bd832023-01-11 14:50:10 +010091static int dhm_check_range(const mbedtls_mpi *param, const mbedtls_mpi *P)
Paul Bakkerc47840e2011-02-20 16:37:30 +000092{
Gilles Peskine8e38acc2021-03-31 22:56:43 +020093 mbedtls_mpi U;
Janos Follathaa325d72017-09-20 15:33:24 +010094 int ret = 0;
Paul Bakkerc47840e2011-02-20 16:37:30 +000095
Gilles Peskine449bd832023-01-11 14:50:10 +010096 mbedtls_mpi_init(&U);
Paul Bakker3d8fb632014-04-17 12:42:41 +020097
Gilles Peskine449bd832023-01-11 14:50:10 +010098 MBEDTLS_MPI_CHK(mbedtls_mpi_sub_int(&U, P, 2));
Paul Bakkerc47840e2011-02-20 16:37:30 +000099
Gilles Peskine449bd832023-01-11 14:50:10 +0100100 if (mbedtls_mpi_cmp_int(param, 2) < 0 ||
101 mbedtls_mpi_cmp_mpi(param, &U) > 0) {
Janos Follathaa325d72017-09-20 15:33:24 +0100102 ret = MBEDTLS_ERR_DHM_BAD_INPUT_DATA;
Paul Bakkerc47840e2011-02-20 16:37:30 +0000103 }
104
Paul Bakker3d8fb632014-04-17 12:42:41 +0200105cleanup:
Gilles Peskine449bd832023-01-11 14:50:10 +0100106 mbedtls_mpi_free(&U);
107 return ret;
Paul Bakkerc47840e2011-02-20 16:37:30 +0000108}
109
Gilles Peskine449bd832023-01-11 14:50:10 +0100110void mbedtls_dhm_init(mbedtls_dhm_context *ctx)
Paul Bakker8f870b02014-06-20 13:32:38 +0200111{
Gilles Peskine449bd832023-01-11 14:50:10 +0100112 memset(ctx, 0, sizeof(mbedtls_dhm_context));
Paul Bakker8f870b02014-06-20 13:32:38 +0200113}
114
Gilles Peskine449bd832023-01-11 14:50:10 +0100115size_t mbedtls_dhm_get_bitlen(const mbedtls_dhm_context *ctx)
Gilles Peskine487bbf62021-05-27 22:17:07 +0200116{
Gilles Peskine449bd832023-01-11 14:50:10 +0100117 return mbedtls_mpi_bitlen(&ctx->P);
Gilles Peskine487bbf62021-05-27 22:17:07 +0200118}
119
Gilles Peskine449bd832023-01-11 14:50:10 +0100120size_t mbedtls_dhm_get_len(const mbedtls_dhm_context *ctx)
Gilles Peskine487bbf62021-05-27 22:17:07 +0200121{
Gilles Peskine449bd832023-01-11 14:50:10 +0100122 return mbedtls_mpi_size(&ctx->P);
Gilles Peskine487bbf62021-05-27 22:17:07 +0200123}
124
Gilles Peskine449bd832023-01-11 14:50:10 +0100125int mbedtls_dhm_get_value(const mbedtls_dhm_context *ctx,
126 mbedtls_dhm_parameter param,
127 mbedtls_mpi *dest)
Gilles Peskine71acc6e2021-05-27 22:50:53 +0200128{
129 const mbedtls_mpi *src = NULL;
Gilles Peskine449bd832023-01-11 14:50:10 +0100130 switch (param) {
Gilles Peskine71acc6e2021-05-27 22:50:53 +0200131 case MBEDTLS_DHM_PARAM_P:
132 src = &ctx->P;
133 break;
134 case MBEDTLS_DHM_PARAM_G:
135 src = &ctx->G;
136 break;
137 case MBEDTLS_DHM_PARAM_X:
138 src = &ctx->X;
139 break;
140 case MBEDTLS_DHM_PARAM_GX:
141 src = &ctx->GX;
142 break;
143 case MBEDTLS_DHM_PARAM_GY:
144 src = &ctx->GY;
145 break;
146 case MBEDTLS_DHM_PARAM_K:
147 src = &ctx->K;
148 break;
149 default:
Gilles Peskine449bd832023-01-11 14:50:10 +0100150 return MBEDTLS_ERR_DHM_BAD_INPUT_DATA;
Gilles Peskine71acc6e2021-05-27 22:50:53 +0200151 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100152 return mbedtls_mpi_copy(dest, src);
Gilles Peskine71acc6e2021-05-27 22:50:53 +0200153}
154
Paul Bakkerc47840e2011-02-20 16:37:30 +0000155/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000156 * Parse the ServerKeyExchange parameters
157 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100158int mbedtls_dhm_read_params(mbedtls_dhm_context *ctx,
159 unsigned char **p,
160 const unsigned char *end)
Paul Bakker5121ce52009-01-03 21:22:43 +0000161{
Janos Follath24eed8d2019-11-22 13:21:35 +0000162 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker5121ce52009-01-03 21:22:43 +0000163
Gilles Peskine449bd832023-01-11 14:50:10 +0100164 if ((ret = dhm_read_bignum(&ctx->P, p, end)) != 0 ||
165 (ret = dhm_read_bignum(&ctx->G, p, end)) != 0 ||
166 (ret = dhm_read_bignum(&ctx->GY, p, end)) != 0) {
167 return ret;
168 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000169
Gilles Peskine449bd832023-01-11 14:50:10 +0100170 if ((ret = dhm_check_range(&ctx->GY, &ctx->P)) != 0) {
171 return ret;
172 }
Paul Bakker345a6fe2011-02-28 21:20:02 +0000173
Gilles Peskine449bd832023-01-11 14:50:10 +0100174 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000175}
176
Gilles Peskine17f1a262021-03-31 22:48:14 +0200177/*
Gilles Peskineda7ee012021-03-31 23:04:50 +0200178 * Pick a random R in the range [2, M-2] for blinding or key generation.
Gilles Peskine17f1a262021-03-31 22:48:14 +0200179 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100180static int dhm_random_below(mbedtls_mpi *R, const mbedtls_mpi *M,
181 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng)
Gilles Peskine17f1a262021-03-31 22:48:14 +0200182{
Gilles Peskineda7ee012021-03-31 23:04:50 +0200183 int ret;
Gilles Peskine17f1a262021-03-31 22:48:14 +0200184
Gilles Peskine449bd832023-01-11 14:50:10 +0100185 MBEDTLS_MPI_CHK(mbedtls_mpi_random(R, 3, M, f_rng, p_rng));
186 MBEDTLS_MPI_CHK(mbedtls_mpi_sub_int(R, R, 1));
Gilles Peskine17f1a262021-03-31 22:48:14 +0200187
188cleanup:
Gilles Peskine449bd832023-01-11 14:50:10 +0100189 return ret;
Gilles Peskine17f1a262021-03-31 22:48:14 +0200190}
191
Gilles Peskine449bd832023-01-11 14:50:10 +0100192static int dhm_make_common(mbedtls_dhm_context *ctx, int x_size,
193 int (*f_rng)(void *, unsigned char *, size_t),
194 void *p_rng)
Paul Bakker5121ce52009-01-03 21:22:43 +0000195{
Gilles Peskine17f1a262021-03-31 22:48:14 +0200196 int ret = 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000197
Gilles Peskine449bd832023-01-11 14:50:10 +0100198 if (mbedtls_mpi_cmp_int(&ctx->P, 0) == 0) {
199 return MBEDTLS_ERR_DHM_BAD_INPUT_DATA;
Paul Bakkeraec37cb2012-04-26 18:59:59 +0000200 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100201 if (x_size < 0) {
202 return MBEDTLS_ERR_DHM_BAD_INPUT_DATA;
203 }
204
205 if ((unsigned) x_size < mbedtls_mpi_size(&ctx->P)) {
206 MBEDTLS_MPI_CHK(mbedtls_mpi_fill_random(&ctx->X, x_size, f_rng, p_rng));
207 } else {
Gilles Peskine17f1a262021-03-31 22:48:14 +0200208 /* Generate X as large as possible ( <= P - 2 ) */
Gilles Peskine449bd832023-01-11 14:50:10 +0100209 ret = dhm_random_below(&ctx->X, &ctx->P, f_rng, p_rng);
210 if (ret == MBEDTLS_ERR_MPI_NOT_ACCEPTABLE) {
211 return MBEDTLS_ERR_DHM_MAKE_PARAMS_FAILED;
212 }
213 if (ret != 0) {
214 return ret;
215 }
Gilles Peskine17f1a262021-03-31 22:48:14 +0200216 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000217
Paul Bakkerff7fe672010-07-18 09:45:05 +0000218 /*
219 * Calculate GX = G^X mod P
220 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100221 MBEDTLS_MPI_CHK(mbedtls_mpi_exp_mod(&ctx->GX, &ctx->G, &ctx->X,
222 &ctx->P, &ctx->RP));
Paul Bakker5121ce52009-01-03 21:22:43 +0000223
Gilles Peskine449bd832023-01-11 14:50:10 +0100224 if ((ret = dhm_check_range(&ctx->GX, &ctx->P)) != 0) {
225 return ret;
226 }
Paul Bakkerc47840e2011-02-20 16:37:30 +0000227
Gilles Peskinecb660f22021-03-31 22:35:13 +0200228cleanup:
Gilles Peskine449bd832023-01-11 14:50:10 +0100229 return ret;
Gilles Peskinecb660f22021-03-31 22:35:13 +0200230}
231
232/*
233 * Setup and write the ServerKeyExchange parameters
234 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100235int mbedtls_dhm_make_params(mbedtls_dhm_context *ctx, int x_size,
236 unsigned char *output, size_t *olen,
237 int (*f_rng)(void *, unsigned char *, size_t),
238 void *p_rng)
Gilles Peskinecb660f22021-03-31 22:35:13 +0200239{
240 int ret;
241 size_t n1, n2, n3;
242 unsigned char *p;
Gilles Peskinecb660f22021-03-31 22:35:13 +0200243
Gilles Peskine449bd832023-01-11 14:50:10 +0100244 ret = dhm_make_common(ctx, x_size, f_rng, p_rng);
245 if (ret != 0) {
Gilles Peskinecb660f22021-03-31 22:35:13 +0200246 goto cleanup;
Gilles Peskine449bd832023-01-11 14:50:10 +0100247 }
Gilles Peskinecb660f22021-03-31 22:35:13 +0200248
Paul Bakker5121ce52009-01-03 21:22:43 +0000249 /*
Gilles Peskine03299dc2021-04-13 22:10:24 +0200250 * Export P, G, GX. RFC 5246 §4.4 states that "leading zero octets are
251 * not required". We omit leading zeros for compactness.
Paul Bakker5121ce52009-01-03 21:22:43 +0000252 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100253#define DHM_MPI_EXPORT(X, n) \
Hanno Beckere71ad122017-09-28 10:32:25 +0100254 do { \
Gilles Peskine449bd832023-01-11 14:50:10 +0100255 MBEDTLS_MPI_CHK(mbedtls_mpi_write_binary((X), \
256 p + 2, \
257 (n))); \
258 *p++ = MBEDTLS_BYTE_1(n); \
259 *p++ = MBEDTLS_BYTE_0(n); \
260 p += (n); \
261 } while (0)
Paul Bakker5121ce52009-01-03 21:22:43 +0000262
Gilles Peskine449bd832023-01-11 14:50:10 +0100263 n1 = mbedtls_mpi_size(&ctx->P);
264 n2 = mbedtls_mpi_size(&ctx->G);
265 n3 = mbedtls_mpi_size(&ctx->GX);
Paul Bakker5121ce52009-01-03 21:22:43 +0000266
267 p = output;
Gilles Peskine449bd832023-01-11 14:50:10 +0100268 DHM_MPI_EXPORT(&ctx->P, n1);
269 DHM_MPI_EXPORT(&ctx->G, n2);
270 DHM_MPI_EXPORT(&ctx->GX, n3);
Paul Bakker5121ce52009-01-03 21:22:43 +0000271
Hanno Beckere71ad122017-09-28 10:32:25 +0100272 *olen = p - output;
Paul Bakker5121ce52009-01-03 21:22:43 +0000273
Paul Bakker5121ce52009-01-03 21:22:43 +0000274cleanup:
Gilles Peskine449bd832023-01-11 14:50:10 +0100275 if (ret != 0 && ret > -128) {
276 ret = MBEDTLS_ERROR_ADD(MBEDTLS_ERR_DHM_MAKE_PARAMS_FAILED, ret);
277 }
278 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +0000279}
280
281/*
Hanno Becker8880e752017-10-04 13:15:08 +0100282 * Set prime modulus and generator
283 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100284int mbedtls_dhm_set_group(mbedtls_dhm_context *ctx,
285 const mbedtls_mpi *P,
286 const mbedtls_mpi *G)
Hanno Becker8880e752017-10-04 13:15:08 +0100287{
Janos Follath24eed8d2019-11-22 13:21:35 +0000288 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Hanno Becker8880e752017-10-04 13:15:08 +0100289
Gilles Peskine449bd832023-01-11 14:50:10 +0100290 if ((ret = mbedtls_mpi_copy(&ctx->P, P)) != 0 ||
291 (ret = mbedtls_mpi_copy(&ctx->G, G)) != 0) {
292 return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_DHM_SET_GROUP_FAILED, ret);
Hanno Becker8880e752017-10-04 13:15:08 +0100293 }
294
Gilles Peskine449bd832023-01-11 14:50:10 +0100295 return 0;
Hanno Becker8880e752017-10-04 13:15:08 +0100296}
297
298/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000299 * Import the peer's public value G^Y
300 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100301int mbedtls_dhm_read_public(mbedtls_dhm_context *ctx,
302 const unsigned char *input, size_t ilen)
Paul Bakker5121ce52009-01-03 21:22:43 +0000303{
Janos Follath24eed8d2019-11-22 13:21:35 +0000304 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker5121ce52009-01-03 21:22:43 +0000305
Gilles Peskine449bd832023-01-11 14:50:10 +0100306 if (ilen < 1 || ilen > mbedtls_dhm_get_len(ctx)) {
307 return MBEDTLS_ERR_DHM_BAD_INPUT_DATA;
308 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000309
Gilles Peskine449bd832023-01-11 14:50:10 +0100310 if ((ret = mbedtls_mpi_read_binary(&ctx->GY, input, ilen)) != 0) {
311 return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_DHM_READ_PUBLIC_FAILED, ret);
312 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000313
Gilles Peskine449bd832023-01-11 14:50:10 +0100314 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000315}
316
317/*
318 * Create own private value X and export G^X
319 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100320int mbedtls_dhm_make_public(mbedtls_dhm_context *ctx, int x_size,
321 unsigned char *output, size_t olen,
322 int (*f_rng)(void *, unsigned char *, size_t),
323 void *p_rng)
Paul Bakker5121ce52009-01-03 21:22:43 +0000324{
Gilles Peskinecb660f22021-03-31 22:35:13 +0200325 int ret;
Paul Bakker5121ce52009-01-03 21:22:43 +0000326
Gilles Peskine449bd832023-01-11 14:50:10 +0100327 if (olen < 1 || olen > mbedtls_dhm_get_len(ctx)) {
328 return MBEDTLS_ERR_DHM_BAD_INPUT_DATA;
329 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000330
Gilles Peskine449bd832023-01-11 14:50:10 +0100331 ret = dhm_make_common(ctx, x_size, f_rng, p_rng);
332 if (ret == MBEDTLS_ERR_DHM_MAKE_PARAMS_FAILED) {
333 return MBEDTLS_ERR_DHM_MAKE_PUBLIC_FAILED;
334 }
335 if (ret != 0) {
Gilles Peskinecb660f22021-03-31 22:35:13 +0200336 goto cleanup;
Gilles Peskine449bd832023-01-11 14:50:10 +0100337 }
Paul Bakkerc47840e2011-02-20 16:37:30 +0000338
Gilles Peskine449bd832023-01-11 14:50:10 +0100339 MBEDTLS_MPI_CHK(mbedtls_mpi_write_binary(&ctx->GX, output, olen));
Paul Bakker5121ce52009-01-03 21:22:43 +0000340
341cleanup:
Gilles Peskine449bd832023-01-11 14:50:10 +0100342 if (ret != 0 && ret > -128) {
343 ret = MBEDTLS_ERROR_ADD(MBEDTLS_ERR_DHM_MAKE_PUBLIC_FAILED, ret);
344 }
345 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +0000346}
347
Manuel Pégourié-Gonnard9f58c4b2020-06-25 12:34:58 +0200348
349/*
Manuel Pégourié-Gonnard143b5022013-09-04 16:29:59 +0200350 * Use the blinding method and optimisation suggested in section 10 of:
351 * KOCHER, Paul C. Timing attacks on implementations of Diffie-Hellman, RSA,
Manuel Pégourié-Gonnard998930a2015-04-03 13:48:06 +0200352 * DSS, and other systems. In : Advances in Cryptology-CRYPTO'96. Springer
Manuel Pégourié-Gonnard143b5022013-09-04 16:29:59 +0200353 * Berlin Heidelberg, 1996. p. 104-113.
354 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100355static int dhm_update_blinding(mbedtls_dhm_context *ctx,
356 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng)
Manuel Pégourié-Gonnard143b5022013-09-04 16:29:59 +0200357{
Manuel Pégourié-Gonnard9f58c4b2020-06-25 12:34:58 +0200358 int ret;
Manuel Pégourié-Gonnardaf721672020-06-25 12:47:22 +0200359 mbedtls_mpi R;
360
Gilles Peskine449bd832023-01-11 14:50:10 +0100361 mbedtls_mpi_init(&R);
Manuel Pégourié-Gonnard143b5022013-09-04 16:29:59 +0200362
363 /*
Manuel Pégourié-Gonnard15d5de12013-09-17 11:34:11 +0200364 * Don't use any blinding the first time a particular X is used,
365 * but remember it to use blinding next time.
Manuel Pégourié-Gonnard143b5022013-09-04 16:29:59 +0200366 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100367 if (mbedtls_mpi_cmp_mpi(&ctx->X, &ctx->pX) != 0) {
368 MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&ctx->pX, &ctx->X));
369 MBEDTLS_MPI_CHK(mbedtls_mpi_lset(&ctx->Vi, 1));
370 MBEDTLS_MPI_CHK(mbedtls_mpi_lset(&ctx->Vf, 1));
Manuel Pégourié-Gonnarded8a02b2013-09-04 16:39:03 +0200371
Gilles Peskine449bd832023-01-11 14:50:10 +0100372 return 0;
Manuel Pégourié-Gonnard143b5022013-09-04 16:29:59 +0200373 }
374
375 /*
Manuel Pégourié-Gonnard15d5de12013-09-17 11:34:11 +0200376 * Ok, we need blinding. Can we re-use existing values?
377 * If yes, just update them by squaring them.
Manuel Pégourié-Gonnard143b5022013-09-04 16:29:59 +0200378 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100379 if (mbedtls_mpi_cmp_int(&ctx->Vi, 1) != 0) {
380 MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(&ctx->Vi, &ctx->Vi, &ctx->Vi));
381 MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(&ctx->Vi, &ctx->Vi, &ctx->P));
Manuel Pégourié-Gonnard15d5de12013-09-17 11:34:11 +0200382
Gilles Peskine449bd832023-01-11 14:50:10 +0100383 MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(&ctx->Vf, &ctx->Vf, &ctx->Vf));
384 MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(&ctx->Vf, &ctx->Vf, &ctx->P));
Manuel Pégourié-Gonnard15d5de12013-09-17 11:34:11 +0200385
Gilles Peskine449bd832023-01-11 14:50:10 +0100386 return 0;
Manuel Pégourié-Gonnard15d5de12013-09-17 11:34:11 +0200387 }
388
389 /*
390 * We need to generate blinding values from scratch
391 */
392
Gilles Peskine7b2b66e2021-03-31 22:50:57 +0200393 /* Vi = random( 2, P-2 ) */
Gilles Peskine449bd832023-01-11 14:50:10 +0100394 MBEDTLS_MPI_CHK(dhm_random_below(&ctx->Vi, &ctx->P, f_rng, p_rng));
Manuel Pégourié-Gonnard15d5de12013-09-17 11:34:11 +0200395
Manuel Pégourié-Gonnardaf721672020-06-25 12:47:22 +0200396 /* Vf = Vi^-X mod P
397 * First compute Vi^-1 = R * (R Vi)^-1, (avoiding leaks from inv_mod),
398 * then elevate to the Xth power. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100399 MBEDTLS_MPI_CHK(dhm_random_below(&R, &ctx->P, f_rng, p_rng));
400 MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(&ctx->Vf, &ctx->Vi, &R));
401 MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(&ctx->Vf, &ctx->Vf, &ctx->P));
402 MBEDTLS_MPI_CHK(mbedtls_mpi_inv_mod(&ctx->Vf, &ctx->Vf, &ctx->P));
403 MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(&ctx->Vf, &ctx->Vf, &R));
404 MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(&ctx->Vf, &ctx->Vf, &ctx->P));
Manuel Pégourié-Gonnard15d5de12013-09-17 11:34:11 +0200405
Gilles Peskine449bd832023-01-11 14:50:10 +0100406 MBEDTLS_MPI_CHK(mbedtls_mpi_exp_mod(&ctx->Vf, &ctx->Vf, &ctx->X, &ctx->P, &ctx->RP));
Manuel Pégourié-Gonnard143b5022013-09-04 16:29:59 +0200407
Manuel Pégourié-Gonnard143b5022013-09-04 16:29:59 +0200408cleanup:
Gilles Peskine449bd832023-01-11 14:50:10 +0100409 mbedtls_mpi_free(&R);
Manuel Pégourié-Gonnardaf721672020-06-25 12:47:22 +0200410
Gilles Peskine449bd832023-01-11 14:50:10 +0100411 return ret;
Manuel Pégourié-Gonnard143b5022013-09-04 16:29:59 +0200412}
413
414/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000415 * Derive and export the shared secret (G^Y)^X mod P
416 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100417int mbedtls_dhm_calc_secret(mbedtls_dhm_context *ctx,
418 unsigned char *output, size_t output_size, size_t *olen,
419 int (*f_rng)(void *, unsigned char *, size_t),
420 void *p_rng)
Paul Bakker5121ce52009-01-03 21:22:43 +0000421{
Janos Follath24eed8d2019-11-22 13:21:35 +0000422 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200423 mbedtls_mpi GYb;
Manuel Pégourié-Gonnard2d627642013-09-04 14:22:07 +0200424
Gilles Peskine449bd832023-01-11 14:50:10 +0100425 if (f_rng == NULL) {
426 return MBEDTLS_ERR_DHM_BAD_INPUT_DATA;
427 }
Manuel Pégourié-Gonnard1a877222021-06-15 11:29:26 +0200428
Gilles Peskine449bd832023-01-11 14:50:10 +0100429 if (output_size < mbedtls_dhm_get_len(ctx)) {
430 return MBEDTLS_ERR_DHM_BAD_INPUT_DATA;
431 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000432
Gilles Peskine449bd832023-01-11 14:50:10 +0100433 if ((ret = dhm_check_range(&ctx->GY, &ctx->P)) != 0) {
434 return ret;
435 }
Paul Bakkerc47840e2011-02-20 16:37:30 +0000436
Gilles Peskine449bd832023-01-11 14:50:10 +0100437 mbedtls_mpi_init(&GYb);
Manuel Pégourié-Gonnard143b5022013-09-04 16:29:59 +0200438
439 /* Blind peer's value */
Gilles Peskine449bd832023-01-11 14:50:10 +0100440 MBEDTLS_MPI_CHK(dhm_update_blinding(ctx, f_rng, p_rng));
441 MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(&GYb, &ctx->GY, &ctx->Vi));
442 MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(&GYb, &GYb, &ctx->P));
Manuel Pégourié-Gonnard143b5022013-09-04 16:29:59 +0200443
444 /* Do modular exponentiation */
Gilles Peskine449bd832023-01-11 14:50:10 +0100445 MBEDTLS_MPI_CHK(mbedtls_mpi_exp_mod(&ctx->K, &GYb, &ctx->X,
446 &ctx->P, &ctx->RP));
Manuel Pégourié-Gonnard143b5022013-09-04 16:29:59 +0200447
448 /* Unblind secret value */
Gilles Peskine449bd832023-01-11 14:50:10 +0100449 MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(&ctx->K, &ctx->K, &ctx->Vf));
450 MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(&ctx->K, &ctx->K, &ctx->P));
Manuel Pégourié-Gonnard143b5022013-09-04 16:29:59 +0200451
Gilles Peskine03299dc2021-04-13 22:10:24 +0200452 /* Output the secret without any leading zero byte. This is mandatory
453 * for TLS per RFC 5246 §8.1.2. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100454 *olen = mbedtls_mpi_size(&ctx->K);
455 MBEDTLS_MPI_CHK(mbedtls_mpi_write_binary(&ctx->K, output, *olen));
Paul Bakker5121ce52009-01-03 21:22:43 +0000456
457cleanup:
Gilles Peskine449bd832023-01-11 14:50:10 +0100458 mbedtls_mpi_free(&GYb);
Paul Bakker5121ce52009-01-03 21:22:43 +0000459
Gilles Peskine449bd832023-01-11 14:50:10 +0100460 if (ret != 0) {
461 return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_DHM_CALC_SECRET_FAILED, ret);
462 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000463
Gilles Peskine449bd832023-01-11 14:50:10 +0100464 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000465}
466
467/*
468 * Free the components of a DHM key
469 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100470void mbedtls_dhm_free(mbedtls_dhm_context *ctx)
Paul Bakker5121ce52009-01-03 21:22:43 +0000471{
Gilles Peskine449bd832023-01-11 14:50:10 +0100472 if (ctx == NULL) {
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500473 return;
Gilles Peskine449bd832023-01-11 14:50:10 +0100474 }
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500475
Gilles Peskine449bd832023-01-11 14:50:10 +0100476 mbedtls_mpi_free(&ctx->pX);
477 mbedtls_mpi_free(&ctx->Vf);
478 mbedtls_mpi_free(&ctx->Vi);
479 mbedtls_mpi_free(&ctx->RP);
480 mbedtls_mpi_free(&ctx->K);
481 mbedtls_mpi_free(&ctx->GY);
482 mbedtls_mpi_free(&ctx->GX);
483 mbedtls_mpi_free(&ctx->X);
484 mbedtls_mpi_free(&ctx->G);
485 mbedtls_mpi_free(&ctx->P);
Manuel Pégourié-Gonnardb72b4ed2013-09-13 13:55:26 +0200486
Gilles Peskine449bd832023-01-11 14:50:10 +0100487 mbedtls_platform_zeroize(ctx, sizeof(mbedtls_dhm_context));
Paul Bakker5121ce52009-01-03 21:22:43 +0000488}
489
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200490#if defined(MBEDTLS_ASN1_PARSE_C)
Paul Bakker40ce79f2013-09-15 17:43:54 +0200491/*
492 * Parse DHM parameters
493 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100494int mbedtls_dhm_parse_dhm(mbedtls_dhm_context *dhm, const unsigned char *dhmin,
495 size_t dhminlen)
Paul Bakker40ce79f2013-09-15 17:43:54 +0200496{
Janos Follath24eed8d2019-11-22 13:21:35 +0000497 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker40ce79f2013-09-15 17:43:54 +0200498 size_t len;
499 unsigned char *p, *end;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200500#if defined(MBEDTLS_PEM_PARSE_C)
501 mbedtls_pem_context pem;
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500502#endif /* MBEDTLS_PEM_PARSE_C */
Paul Bakker40ce79f2013-09-15 17:43:54 +0200503
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500504#if defined(MBEDTLS_PEM_PARSE_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100505 mbedtls_pem_init(&pem);
Paul Bakker40ce79f2013-09-15 17:43:54 +0200506
Manuel Pégourié-Gonnard43b37cb2015-05-12 11:20:10 +0200507 /* Avoid calling mbedtls_pem_read_buffer() on non-null-terminated string */
Gilles Peskine449bd832023-01-11 14:50:10 +0100508 if (dhminlen == 0 || dhmin[dhminlen - 1] != '\0') {
Manuel Pégourié-Gonnard43b37cb2015-05-12 11:20:10 +0200509 ret = MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT;
Gilles Peskine449bd832023-01-11 14:50:10 +0100510 } else {
511 ret = mbedtls_pem_read_buffer(&pem,
512 "-----BEGIN DH PARAMETERS-----",
513 "-----END DH PARAMETERS-----",
514 dhmin, NULL, 0, &dhminlen);
515 }
Paul Bakker40ce79f2013-09-15 17:43:54 +0200516
Gilles Peskine449bd832023-01-11 14:50:10 +0100517 if (ret == 0) {
Paul Bakker40ce79f2013-09-15 17:43:54 +0200518 /*
519 * Was PEM encoded
520 */
521 dhminlen = pem.buflen;
Gilles Peskine449bd832023-01-11 14:50:10 +0100522 } else if (ret != MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT) {
Paul Bakker40ce79f2013-09-15 17:43:54 +0200523 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100524 }
Paul Bakker40ce79f2013-09-15 17:43:54 +0200525
Gilles Peskine449bd832023-01-11 14:50:10 +0100526 p = (ret == 0) ? pem.buf : (unsigned char *) dhmin;
Paul Bakker40ce79f2013-09-15 17:43:54 +0200527#else
528 p = (unsigned char *) dhmin;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200529#endif /* MBEDTLS_PEM_PARSE_C */
Paul Bakker40ce79f2013-09-15 17:43:54 +0200530 end = p + dhminlen;
531
532 /*
533 * DHParams ::= SEQUENCE {
Daniel Kahn Gillmor2ed81732015-04-03 13:09:24 -0400534 * prime INTEGER, -- P
535 * generator INTEGER, -- g
536 * privateValueLength INTEGER OPTIONAL
Paul Bakker40ce79f2013-09-15 17:43:54 +0200537 * }
538 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100539 if ((ret = mbedtls_asn1_get_tag(&p, end, &len,
540 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) {
541 ret = MBEDTLS_ERROR_ADD(MBEDTLS_ERR_DHM_INVALID_FORMAT, ret);
Paul Bakker40ce79f2013-09-15 17:43:54 +0200542 goto exit;
543 }
544
545 end = p + len;
546
Gilles Peskine449bd832023-01-11 14:50:10 +0100547 if ((ret = mbedtls_asn1_get_mpi(&p, end, &dhm->P)) != 0 ||
548 (ret = mbedtls_asn1_get_mpi(&p, end, &dhm->G)) != 0) {
549 ret = MBEDTLS_ERROR_ADD(MBEDTLS_ERR_DHM_INVALID_FORMAT, ret);
Paul Bakker40ce79f2013-09-15 17:43:54 +0200550 goto exit;
551 }
552
Gilles Peskine449bd832023-01-11 14:50:10 +0100553 if (p != end) {
Manuel Pégourié-Gonnardde9b3632015-04-17 20:06:31 +0200554 /* This might be the optional privateValueLength.
555 * If so, we can cleanly discard it */
556 mbedtls_mpi rec;
Gilles Peskine449bd832023-01-11 14:50:10 +0100557 mbedtls_mpi_init(&rec);
558 ret = mbedtls_asn1_get_mpi(&p, end, &rec);
559 mbedtls_mpi_free(&rec);
560 if (ret != 0) {
561 ret = MBEDTLS_ERROR_ADD(MBEDTLS_ERR_DHM_INVALID_FORMAT, ret);
Daniel Kahn Gillmor2ed81732015-04-03 13:09:24 -0400562 goto exit;
563 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100564 if (p != end) {
565 ret = MBEDTLS_ERROR_ADD(MBEDTLS_ERR_DHM_INVALID_FORMAT,
566 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
Daniel Kahn Gillmor2ed81732015-04-03 13:09:24 -0400567 goto exit;
568 }
Paul Bakker40ce79f2013-09-15 17:43:54 +0200569 }
570
571 ret = 0;
572
573exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200574#if defined(MBEDTLS_PEM_PARSE_C)
Gilles Peskine449bd832023-01-11 14:50:10 +0100575 mbedtls_pem_free(&pem);
Paul Bakker40ce79f2013-09-15 17:43:54 +0200576#endif
Gilles Peskine449bd832023-01-11 14:50:10 +0100577 if (ret != 0) {
578 mbedtls_dhm_free(dhm);
579 }
Paul Bakker40ce79f2013-09-15 17:43:54 +0200580
Gilles Peskine449bd832023-01-11 14:50:10 +0100581 return ret;
Paul Bakker40ce79f2013-09-15 17:43:54 +0200582}
583
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200584#if defined(MBEDTLS_FS_IO)
Paul Bakker40ce79f2013-09-15 17:43:54 +0200585/*
586 * Load all data from a file into a given buffer.
Manuel Pégourié-Gonnard43b37cb2015-05-12 11:20:10 +0200587 *
588 * The file is expected to contain either PEM or DER encoded data.
589 * A terminating null byte is always appended. It is included in the announced
590 * length only if the data looks like it is PEM encoded.
Paul Bakker40ce79f2013-09-15 17:43:54 +0200591 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100592static int load_file(const char *path, unsigned char **buf, size_t *n)
Paul Bakker40ce79f2013-09-15 17:43:54 +0200593{
594 FILE *f;
595 long size;
596
Gilles Peskine449bd832023-01-11 14:50:10 +0100597 if ((f = fopen(path, "rb")) == NULL) {
598 return MBEDTLS_ERR_DHM_FILE_IO_ERROR;
599 }
Gilles Peskineda0913b2022-06-30 17:03:40 +0200600 /* The data loaded here is public, so don't bother disabling buffering. */
Paul Bakker40ce79f2013-09-15 17:43:54 +0200601
Gilles Peskine449bd832023-01-11 14:50:10 +0100602 fseek(f, 0, SEEK_END);
603 if ((size = ftell(f)) == -1) {
604 fclose(f);
605 return MBEDTLS_ERR_DHM_FILE_IO_ERROR;
Paul Bakker40ce79f2013-09-15 17:43:54 +0200606 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100607 fseek(f, 0, SEEK_SET);
Paul Bakker40ce79f2013-09-15 17:43:54 +0200608
609 *n = (size_t) size;
610
Gilles Peskine449bd832023-01-11 14:50:10 +0100611 if (*n + 1 == 0 ||
612 (*buf = mbedtls_calloc(1, *n + 1)) == NULL) {
613 fclose(f);
614 return MBEDTLS_ERR_DHM_ALLOC_FAILED;
Paul Bakker40ce79f2013-09-15 17:43:54 +0200615 }
616
Gilles Peskine449bd832023-01-11 14:50:10 +0100617 if (fread(*buf, 1, *n, f) != *n) {
618 fclose(f);
Andres Amaya Garciabdbca7b2017-06-23 16:23:21 +0100619
Tom Cosgroveca8c61b2023-07-17 15:17:40 +0100620 mbedtls_zeroize_and_free(*buf, *n + 1);
Andres Amaya Garciabdbca7b2017-06-23 16:23:21 +0100621
Gilles Peskine449bd832023-01-11 14:50:10 +0100622 return MBEDTLS_ERR_DHM_FILE_IO_ERROR;
Paul Bakker40ce79f2013-09-15 17:43:54 +0200623 }
624
Gilles Peskine449bd832023-01-11 14:50:10 +0100625 fclose(f);
Paul Bakker40ce79f2013-09-15 17:43:54 +0200626
627 (*buf)[*n] = '\0';
628
Gilles Peskine449bd832023-01-11 14:50:10 +0100629 if (strstr((const char *) *buf, "-----BEGIN ") != NULL) {
Manuel Pégourié-Gonnard43b37cb2015-05-12 11:20:10 +0200630 ++*n;
Gilles Peskine449bd832023-01-11 14:50:10 +0100631 }
Manuel Pégourié-Gonnard43b37cb2015-05-12 11:20:10 +0200632
Gilles Peskine449bd832023-01-11 14:50:10 +0100633 return 0;
Paul Bakker40ce79f2013-09-15 17:43:54 +0200634}
635
636/*
637 * Load and parse DHM parameters
638 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100639int mbedtls_dhm_parse_dhmfile(mbedtls_dhm_context *dhm, const char *path)
Paul Bakker40ce79f2013-09-15 17:43:54 +0200640{
Janos Follath24eed8d2019-11-22 13:21:35 +0000641 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker40ce79f2013-09-15 17:43:54 +0200642 size_t n;
643 unsigned char *buf;
644
Gilles Peskine449bd832023-01-11 14:50:10 +0100645 if ((ret = load_file(path, &buf, &n)) != 0) {
646 return ret;
647 }
Paul Bakker40ce79f2013-09-15 17:43:54 +0200648
Gilles Peskine449bd832023-01-11 14:50:10 +0100649 ret = mbedtls_dhm_parse_dhm(dhm, buf, n);
Paul Bakker40ce79f2013-09-15 17:43:54 +0200650
Tom Cosgroveca8c61b2023-07-17 15:17:40 +0100651 mbedtls_zeroize_and_free(buf, n);
Paul Bakker40ce79f2013-09-15 17:43:54 +0200652
Gilles Peskine449bd832023-01-11 14:50:10 +0100653 return ret;
Paul Bakker40ce79f2013-09-15 17:43:54 +0200654}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200655#endif /* MBEDTLS_FS_IO */
656#endif /* MBEDTLS_ASN1_PARSE_C */
nirekh0149762fa2017-12-25 06:46:48 +0000657#endif /* MBEDTLS_DHM_ALT */
Paul Bakker40ce79f2013-09-15 17:43:54 +0200658
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200659#if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +0000660
Hanno Becker8b0f9e62019-05-31 17:28:59 +0100661#if defined(MBEDTLS_PEM_PARSE_C)
Manuel Pégourié-Gonnard53585ee2015-06-25 08:52:25 +0200662static const char mbedtls_test_dhm_params[] =
Gilles Peskine449bd832023-01-11 14:50:10 +0100663 "-----BEGIN DH PARAMETERS-----\r\n"
664 "MIGHAoGBAJ419DBEOgmQTzo5qXl5fQcN9TN455wkOL7052HzxxRVMyhYmwQcgJvh\r\n"
665 "1sa18fyfR9OiVEMYglOpkqVoGLN7qd5aQNNi5W7/C+VBdHTBJcGZJyyP5B3qcz32\r\n"
666 "9mLJKudlVudV0Qxk5qUJaPZ/xupz0NyoVpviuiBOI1gNi8ovSXWzAgEC\r\n"
667 "-----END DH PARAMETERS-----\r\n";
Hanno Becker8b0f9e62019-05-31 17:28:59 +0100668#else /* MBEDTLS_PEM_PARSE_C */
669static const char mbedtls_test_dhm_params[] = {
Gilles Peskine449bd832023-01-11 14:50:10 +0100670 0x30, 0x81, 0x87, 0x02, 0x81, 0x81, 0x00, 0x9e, 0x35, 0xf4, 0x30, 0x44,
671 0x3a, 0x09, 0x90, 0x4f, 0x3a, 0x39, 0xa9, 0x79, 0x79, 0x7d, 0x07, 0x0d,
672 0xf5, 0x33, 0x78, 0xe7, 0x9c, 0x24, 0x38, 0xbe, 0xf4, 0xe7, 0x61, 0xf3,
673 0xc7, 0x14, 0x55, 0x33, 0x28, 0x58, 0x9b, 0x04, 0x1c, 0x80, 0x9b, 0xe1,
674 0xd6, 0xc6, 0xb5, 0xf1, 0xfc, 0x9f, 0x47, 0xd3, 0xa2, 0x54, 0x43, 0x18,
675 0x82, 0x53, 0xa9, 0x92, 0xa5, 0x68, 0x18, 0xb3, 0x7b, 0xa9, 0xde, 0x5a,
676 0x40, 0xd3, 0x62, 0xe5, 0x6e, 0xff, 0x0b, 0xe5, 0x41, 0x74, 0x74, 0xc1,
677 0x25, 0xc1, 0x99, 0x27, 0x2c, 0x8f, 0xe4, 0x1d, 0xea, 0x73, 0x3d, 0xf6,
678 0xf6, 0x62, 0xc9, 0x2a, 0xe7, 0x65, 0x56, 0xe7, 0x55, 0xd1, 0x0c, 0x64,
679 0xe6, 0xa5, 0x09, 0x68, 0xf6, 0x7f, 0xc6, 0xea, 0x73, 0xd0, 0xdc, 0xa8,
680 0x56, 0x9b, 0xe2, 0xba, 0x20, 0x4e, 0x23, 0x58, 0x0d, 0x8b, 0xca, 0x2f,
681 0x49, 0x75, 0xb3, 0x02, 0x01, 0x02
682};
Hanno Becker8b0f9e62019-05-31 17:28:59 +0100683#endif /* MBEDTLS_PEM_PARSE_C */
Manuel Pégourié-Gonnard53585ee2015-06-25 08:52:25 +0200684
Gilles Peskine449bd832023-01-11 14:50:10 +0100685static const size_t mbedtls_test_dhm_params_len = sizeof(mbedtls_test_dhm_params);
Paul Bakker40ce79f2013-09-15 17:43:54 +0200686
Paul Bakker5121ce52009-01-03 21:22:43 +0000687/*
688 * Checkup routine
689 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100690int mbedtls_dhm_self_test(int verbose)
Paul Bakker5121ce52009-01-03 21:22:43 +0000691{
Janos Follath24eed8d2019-11-22 13:21:35 +0000692 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200693 mbedtls_dhm_context dhm;
Paul Bakker40ce79f2013-09-15 17:43:54 +0200694
Gilles Peskine449bd832023-01-11 14:50:10 +0100695 mbedtls_dhm_init(&dhm);
Paul Bakker8f870b02014-06-20 13:32:38 +0200696
Gilles Peskine449bd832023-01-11 14:50:10 +0100697 if (verbose != 0) {
698 mbedtls_printf(" DHM parameter load: ");
699 }
Paul Bakker40ce79f2013-09-15 17:43:54 +0200700
Gilles Peskine449bd832023-01-11 14:50:10 +0100701 if ((ret = mbedtls_dhm_parse_dhm(&dhm,
702 (const unsigned char *) mbedtls_test_dhm_params,
703 mbedtls_test_dhm_params_len)) != 0) {
704 if (verbose != 0) {
705 mbedtls_printf("failed\n");
706 }
Paul Bakker40ce79f2013-09-15 17:43:54 +0200707
Manuel Pégourié-Gonnardb196fc22014-07-09 16:53:29 +0200708 ret = 1;
Paul Bakker8f870b02014-06-20 13:32:38 +0200709 goto exit;
Paul Bakker40ce79f2013-09-15 17:43:54 +0200710 }
711
Gilles Peskine449bd832023-01-11 14:50:10 +0100712 if (verbose != 0) {
713 mbedtls_printf("passed\n\n");
714 }
Paul Bakker40ce79f2013-09-15 17:43:54 +0200715
Paul Bakker8f870b02014-06-20 13:32:38 +0200716exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100717 mbedtls_dhm_free(&dhm);
Paul Bakker40ce79f2013-09-15 17:43:54 +0200718
Gilles Peskine449bd832023-01-11 14:50:10 +0100719 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +0000720}
721
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200722#endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +0000723
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200724#endif /* MBEDTLS_DHM_C */