blob: 6ee54024286bef3d05302c81574f6d4712ad2c41 [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 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020053static int dhm_read_bignum( mbedtls_mpi *X,
Paul Bakker5121ce52009-01-03 21:22:43 +000054 unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +000055 const unsigned char *end )
Paul Bakker5121ce52009-01-03 21:22:43 +000056{
57 int ret, n;
58
59 if( end - *p < 2 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020060 return( MBEDTLS_ERR_DHM_BAD_INPUT_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +000061
62 n = ( (*p)[0] << 8 ) | (*p)[1];
63 (*p) += 2;
64
65 if( (int)( end - *p ) < n )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020066 return( MBEDTLS_ERR_DHM_BAD_INPUT_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +000067
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020068 if( ( ret = mbedtls_mpi_read_binary( X, *p, n ) ) != 0 )
Chris Jones9f7a6932021-04-14 12:12:09 +010069 return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_DHM_READ_PARAMS_FAILED, ret ) );
Paul Bakker5121ce52009-01-03 21:22:43 +000070
71 (*p) += n;
72
73 return( 0 );
74}
75
76/*
Paul Bakkeraec37cb2012-04-26 18:59:59 +000077 * Verify sanity of parameter with regards to P
Paul Bakker345a6fe2011-02-28 21:20:02 +000078 *
Paul Bakkeraec37cb2012-04-26 18:59:59 +000079 * Parameter should be: 2 <= public_param <= P - 2
Paul Bakker345a6fe2011-02-28 21:20:02 +000080 *
Janos Follathaa325d72017-09-20 15:33:24 +010081 * This means that we need to return an error if
Janos Follath1ad1c6d2017-09-21 09:02:11 +010082 * public_param < 2 or public_param > P-2
Janos Follathaa325d72017-09-20 15:33:24 +010083 *
Paul Bakker345a6fe2011-02-28 21:20:02 +000084 * For more information on the attack, see:
85 * http://www.cl.cam.ac.uk/~rja14/Papers/psandqs.pdf
86 * http://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2005-2643
Paul Bakkerc47840e2011-02-20 16:37:30 +000087 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020088static int dhm_check_range( const mbedtls_mpi *param, const mbedtls_mpi *P )
Paul Bakkerc47840e2011-02-20 16:37:30 +000089{
Gilles Peskine8e38acc2021-03-31 22:56:43 +020090 mbedtls_mpi U;
Janos Follathaa325d72017-09-20 15:33:24 +010091 int ret = 0;
Paul Bakkerc47840e2011-02-20 16:37:30 +000092
Gilles Peskine8e38acc2021-03-31 22:56:43 +020093 mbedtls_mpi_init( &U );
Paul Bakker3d8fb632014-04-17 12:42:41 +020094
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020095 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &U, P, 2 ) );
Paul Bakkerc47840e2011-02-20 16:37:30 +000096
Gilles Peskine8e38acc2021-03-31 22:56:43 +020097 if( mbedtls_mpi_cmp_int( param, 2 ) < 0 ||
Janos Follathaa325d72017-09-20 15:33:24 +010098 mbedtls_mpi_cmp_mpi( param, &U ) > 0 )
Paul Bakkerc47840e2011-02-20 16:37:30 +000099 {
Janos Follathaa325d72017-09-20 15:33:24 +0100100 ret = MBEDTLS_ERR_DHM_BAD_INPUT_DATA;
Paul Bakkerc47840e2011-02-20 16:37:30 +0000101 }
102
Paul Bakker3d8fb632014-04-17 12:42:41 +0200103cleanup:
Gilles Peskine8e38acc2021-03-31 22:56:43 +0200104 mbedtls_mpi_free( &U );
Paul Bakker345a6fe2011-02-28 21:20:02 +0000105 return( ret );
Paul Bakkerc47840e2011-02-20 16:37:30 +0000106}
107
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200108void mbedtls_dhm_init( mbedtls_dhm_context *ctx )
Paul Bakker8f870b02014-06-20 13:32:38 +0200109{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200110 memset( ctx, 0, sizeof( mbedtls_dhm_context ) );
Paul Bakker8f870b02014-06-20 13:32:38 +0200111}
112
Gilles Peskine487bbf62021-05-27 22:17:07 +0200113size_t mbedtls_dhm_get_bitlen( const mbedtls_dhm_context *ctx )
114{
115 return( mbedtls_mpi_bitlen( &ctx->P ) );
116}
117
118size_t mbedtls_dhm_get_len( const mbedtls_dhm_context *ctx )
119{
120 return( mbedtls_mpi_size( &ctx->P ) );
121}
122
Gilles Peskinee5702482021-06-11 21:59:08 +0200123int mbedtls_dhm_get_value( const mbedtls_dhm_context *ctx,
124 mbedtls_dhm_parameter param,
125 mbedtls_mpi *dest )
Gilles Peskine71acc6e2021-05-27 22:50:53 +0200126{
127 const mbedtls_mpi *src = NULL;
128 switch( param )
129 {
130 case MBEDTLS_DHM_PARAM_P:
131 src = &ctx->P;
132 break;
133 case MBEDTLS_DHM_PARAM_G:
134 src = &ctx->G;
135 break;
136 case MBEDTLS_DHM_PARAM_X:
137 src = &ctx->X;
138 break;
139 case MBEDTLS_DHM_PARAM_GX:
140 src = &ctx->GX;
141 break;
142 case MBEDTLS_DHM_PARAM_GY:
143 src = &ctx->GY;
144 break;
145 case MBEDTLS_DHM_PARAM_K:
146 src = &ctx->K;
147 break;
148 default:
149 return( MBEDTLS_ERR_DHM_BAD_INPUT_DATA );
150 }
151 return( mbedtls_mpi_copy( dest, src ) );
152}
153
Paul Bakkerc47840e2011-02-20 16:37:30 +0000154/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000155 * Parse the ServerKeyExchange parameters
156 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200157int mbedtls_dhm_read_params( mbedtls_dhm_context *ctx,
Paul Bakker5121ce52009-01-03 21:22:43 +0000158 unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000159 const unsigned char *end )
Paul Bakker5121ce52009-01-03 21:22:43 +0000160{
Janos Follath24eed8d2019-11-22 13:21:35 +0000161 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker5121ce52009-01-03 21:22:43 +0000162
Paul Bakker5121ce52009-01-03 21:22:43 +0000163 if( ( ret = dhm_read_bignum( &ctx->P, p, end ) ) != 0 ||
164 ( ret = dhm_read_bignum( &ctx->G, p, end ) ) != 0 ||
165 ( ret = dhm_read_bignum( &ctx->GY, p, end ) ) != 0 )
166 return( ret );
167
Paul Bakker345a6fe2011-02-28 21:20:02 +0000168 if( ( ret = dhm_check_range( &ctx->GY, &ctx->P ) ) != 0 )
169 return( ret );
170
Paul Bakker5121ce52009-01-03 21:22:43 +0000171 return( 0 );
172}
173
Gilles Peskine17f1a262021-03-31 22:48:14 +0200174/*
Gilles Peskineda7ee012021-03-31 23:04:50 +0200175 * Pick a random R in the range [2, M-2] for blinding or key generation.
Gilles Peskine17f1a262021-03-31 22:48:14 +0200176 */
177static int dhm_random_below( mbedtls_mpi *R, const mbedtls_mpi *M,
178 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
179{
Gilles Peskineda7ee012021-03-31 23:04:50 +0200180 int ret;
Gilles Peskine17f1a262021-03-31 22:48:14 +0200181
Gilles Peskineda7ee012021-03-31 23:04:50 +0200182 MBEDTLS_MPI_CHK( mbedtls_mpi_random( R, 3, M, f_rng, p_rng ) );
183 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( R, R, 1 ) );
Gilles Peskine17f1a262021-03-31 22:48:14 +0200184
185cleanup:
186 return( ret );
187}
188
Gilles Peskinecb660f22021-03-31 22:35:13 +0200189static int dhm_make_common( mbedtls_dhm_context *ctx, int x_size,
190 int (*f_rng)(void *, unsigned char *, size_t),
191 void *p_rng )
Paul Bakker5121ce52009-01-03 21:22:43 +0000192{
Gilles Peskine17f1a262021-03-31 22:48:14 +0200193 int ret = 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000194
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200195 if( mbedtls_mpi_cmp_int( &ctx->P, 0 ) == 0 )
196 return( MBEDTLS_ERR_DHM_BAD_INPUT_DATA );
Gilles Peskine17f1a262021-03-31 22:48:14 +0200197 if( x_size < 0 )
198 return( MBEDTLS_ERR_DHM_BAD_INPUT_DATA );
Paul Bakkerb5b20f12012-09-16 15:07:49 +0000199
Gilles Peskine17f1a262021-03-31 22:48:14 +0200200 if( (unsigned) x_size < mbedtls_mpi_size( &ctx->P ) )
Paul Bakkeraec37cb2012-04-26 18:59:59 +0000201 {
Ron Eldor7269fee2017-01-12 14:50:50 +0200202 MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( &ctx->X, x_size, f_rng, p_rng ) );
Paul Bakkeraec37cb2012-04-26 18:59:59 +0000203 }
Gilles Peskine17f1a262021-03-31 22:48:14 +0200204 else
205 {
206 /* Generate X as large as possible ( <= P - 2 ) */
207 ret = dhm_random_below( &ctx->X, &ctx->P, f_rng, p_rng );
208 if( ret == MBEDTLS_ERR_MPI_NOT_ACCEPTABLE )
209 return( MBEDTLS_ERR_DHM_MAKE_PARAMS_FAILED );
210 if( ret != 0 )
211 return( ret );
212 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000213
Paul Bakkerff7fe672010-07-18 09:45:05 +0000214 /*
215 * Calculate GX = G^X mod P
216 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200217 MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &ctx->GX, &ctx->G, &ctx->X,
Paul Bakker5121ce52009-01-03 21:22:43 +0000218 &ctx->P , &ctx->RP ) );
219
Paul Bakker345a6fe2011-02-28 21:20:02 +0000220 if( ( ret = dhm_check_range( &ctx->GX, &ctx->P ) ) != 0 )
Paul Bakkerc47840e2011-02-20 16:37:30 +0000221 return( ret );
222
Gilles Peskinecb660f22021-03-31 22:35:13 +0200223cleanup:
224 return( ret );
225}
226
227/*
228 * Setup and write the ServerKeyExchange parameters
229 */
230int mbedtls_dhm_make_params( mbedtls_dhm_context *ctx, int x_size,
231 unsigned char *output, size_t *olen,
232 int (*f_rng)(void *, unsigned char *, size_t),
233 void *p_rng )
234{
235 int ret;
236 size_t n1, n2, n3;
237 unsigned char *p;
Gilles Peskinecb660f22021-03-31 22:35:13 +0200238
239 ret = dhm_make_common( ctx, x_size, f_rng, p_rng );
240 if( ret != 0 )
241 goto cleanup;
242
Paul Bakker5121ce52009-01-03 21:22:43 +0000243 /*
Gilles Peskine03299dc2021-04-13 22:10:24 +0200244 * Export P, G, GX. RFC 5246 §4.4 states that "leading zero octets are
245 * not required". We omit leading zeros for compactness.
Paul Bakker5121ce52009-01-03 21:22:43 +0000246 */
Hanno Beckerde6c1642017-10-02 15:03:15 +0100247#define DHM_MPI_EXPORT( X, n ) \
Hanno Beckere71ad122017-09-28 10:32:25 +0100248 do { \
Hanno Beckerde6c1642017-10-02 15:03:15 +0100249 MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( ( X ), \
250 p + 2, \
251 ( n ) ) ); \
Joe Subbianifbeb6922021-07-16 14:27:50 +0100252 *p++ = MBEDTLS_BYTE_1( n ); \
253 *p++ = MBEDTLS_BYTE_0( n ); \
Hanno Beckerde6c1642017-10-02 15:03:15 +0100254 p += ( n ); \
Hanno Beckere71ad122017-09-28 10:32:25 +0100255 } while( 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000256
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200257 n1 = mbedtls_mpi_size( &ctx->P );
258 n2 = mbedtls_mpi_size( &ctx->G );
259 n3 = mbedtls_mpi_size( &ctx->GX );
Paul Bakker5121ce52009-01-03 21:22:43 +0000260
261 p = output;
262 DHM_MPI_EXPORT( &ctx->P , n1 );
263 DHM_MPI_EXPORT( &ctx->G , n2 );
264 DHM_MPI_EXPORT( &ctx->GX, n3 );
265
Hanno Beckere71ad122017-09-28 10:32:25 +0100266 *olen = p - output;
Paul Bakker5121ce52009-01-03 21:22:43 +0000267
Paul Bakker5121ce52009-01-03 21:22:43 +0000268cleanup:
Gilles Peskinecb660f22021-03-31 22:35:13 +0200269 if( ret != 0 && ret > -128 )
270 ret = MBEDTLS_ERROR_ADD( MBEDTLS_ERR_DHM_MAKE_PARAMS_FAILED, ret );
271 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000272}
273
274/*
Hanno Becker8880e752017-10-04 13:15:08 +0100275 * Set prime modulus and generator
276 */
277int mbedtls_dhm_set_group( mbedtls_dhm_context *ctx,
278 const mbedtls_mpi *P,
279 const mbedtls_mpi *G )
280{
Janos Follath24eed8d2019-11-22 13:21:35 +0000281 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Hanno Becker8880e752017-10-04 13:15:08 +0100282
283 if( ( ret = mbedtls_mpi_copy( &ctx->P, P ) ) != 0 ||
284 ( ret = mbedtls_mpi_copy( &ctx->G, G ) ) != 0 )
285 {
Chris Jones9f7a6932021-04-14 12:12:09 +0100286 return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_DHM_SET_GROUP_FAILED, ret ) );
Hanno Becker8880e752017-10-04 13:15:08 +0100287 }
288
Hanno Becker8880e752017-10-04 13:15:08 +0100289 return( 0 );
290}
291
292/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000293 * Import the peer's public value G^Y
294 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200295int mbedtls_dhm_read_public( mbedtls_dhm_context *ctx,
Paul Bakker23986e52011-04-24 08:57:21 +0000296 const unsigned char *input, size_t ilen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000297{
Janos Follath24eed8d2019-11-22 13:21:35 +0000298 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker5121ce52009-01-03 21:22:43 +0000299
Gilles Peskine487bbf62021-05-27 22:17:07 +0200300 if( ilen < 1 || ilen > mbedtls_dhm_get_len( ctx ) )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200301 return( MBEDTLS_ERR_DHM_BAD_INPUT_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +0000302
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200303 if( ( ret = mbedtls_mpi_read_binary( &ctx->GY, input, ilen ) ) != 0 )
Chris Jones9f7a6932021-04-14 12:12:09 +0100304 return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_DHM_READ_PUBLIC_FAILED, ret ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000305
306 return( 0 );
307}
308
309/*
310 * Create own private value X and export G^X
311 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200312int mbedtls_dhm_make_public( mbedtls_dhm_context *ctx, int x_size,
Paul Bakker23986e52011-04-24 08:57:21 +0000313 unsigned char *output, size_t olen,
Paul Bakkera3d195c2011-11-27 21:07:34 +0000314 int (*f_rng)(void *, unsigned char *, size_t),
315 void *p_rng )
Paul Bakker5121ce52009-01-03 21:22:43 +0000316{
Gilles Peskinecb660f22021-03-31 22:35:13 +0200317 int ret;
Paul Bakker5121ce52009-01-03 21:22:43 +0000318
Gilles Peskine487bbf62021-05-27 22:17:07 +0200319 if( olen < 1 || olen > mbedtls_dhm_get_len( ctx ) )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200320 return( MBEDTLS_ERR_DHM_BAD_INPUT_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +0000321
Gilles Peskinecb660f22021-03-31 22:35:13 +0200322 ret = dhm_make_common( ctx, x_size, f_rng, p_rng );
323 if( ret == MBEDTLS_ERR_DHM_MAKE_PARAMS_FAILED )
324 return( MBEDTLS_ERR_DHM_MAKE_PUBLIC_FAILED );
325 if( ret != 0 )
326 goto cleanup;
Paul Bakkerc47840e2011-02-20 16:37:30 +0000327
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200328 MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &ctx->GX, output, olen ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000329
330cleanup:
Gilles Peskinecb660f22021-03-31 22:35:13 +0200331 if( ret != 0 && ret > -128 )
332 ret = MBEDTLS_ERROR_ADD( MBEDTLS_ERR_DHM_MAKE_PUBLIC_FAILED, ret );
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 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200343static int dhm_update_blinding( mbedtls_dhm_context *ctx,
Manuel Pégourié-Gonnard143b5022013-09-04 16:29:59 +0200344 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
345{
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
349 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 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200355 if( mbedtls_mpi_cmp_mpi( &ctx->X, &ctx->pX ) != 0 )
Manuel Pégourié-Gonnarded8a02b2013-09-04 16:39:03 +0200356 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200357 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &ctx->pX, &ctx->X ) );
358 MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &ctx->Vi, 1 ) );
359 MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &ctx->Vf, 1 ) );
Manuel Pégourié-Gonnarded8a02b2013-09-04 16:39:03 +0200360
Manuel Pégourié-Gonnard143b5022013-09-04 16:29:59 +0200361 return( 0 );
362 }
363
364 /*
Manuel Pégourié-Gonnard15d5de12013-09-17 11:34:11 +0200365 * Ok, we need blinding. Can we re-use existing values?
366 * If yes, just update them by squaring them.
Manuel Pégourié-Gonnard143b5022013-09-04 16:29:59 +0200367 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200368 if( mbedtls_mpi_cmp_int( &ctx->Vi, 1 ) != 0 )
Manuel Pégourié-Gonnard15d5de12013-09-17 11:34:11 +0200369 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200370 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &ctx->Vi, &ctx->Vi, &ctx->Vi ) );
371 MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &ctx->Vi, &ctx->Vi, &ctx->P ) );
Manuel Pégourié-Gonnard15d5de12013-09-17 11:34:11 +0200372
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200373 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &ctx->Vf, &ctx->Vf, &ctx->Vf ) );
374 MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &ctx->Vf, &ctx->Vf, &ctx->P ) );
Manuel Pégourié-Gonnard15d5de12013-09-17 11:34:11 +0200375
376 return( 0 );
377 }
378
379 /*
380 * We need to generate blinding values from scratch
381 */
382
Gilles Peskine7b2b66e2021-03-31 22:50:57 +0200383 /* Vi = random( 2, P-2 ) */
Manuel Pégourié-Gonnard9f58c4b2020-06-25 12:34:58 +0200384 MBEDTLS_MPI_CHK( dhm_random_below( &ctx->Vi, &ctx->P, f_rng, p_rng ) );
Manuel Pégourié-Gonnard15d5de12013-09-17 11:34:11 +0200385
Manuel Pégourié-Gonnardaf721672020-06-25 12:47:22 +0200386 /* Vf = Vi^-X mod P
387 * First compute Vi^-1 = R * (R Vi)^-1, (avoiding leaks from inv_mod),
388 * then elevate to the Xth power. */
389 MBEDTLS_MPI_CHK( dhm_random_below( &R, &ctx->P, f_rng, p_rng ) );
390 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &ctx->Vf, &ctx->Vi, &R ) );
391 MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &ctx->Vf, &ctx->Vf, &ctx->P ) );
392 MBEDTLS_MPI_CHK( mbedtls_mpi_inv_mod( &ctx->Vf, &ctx->Vf, &ctx->P ) );
393 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &ctx->Vf, &ctx->Vf, &R ) );
394 MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &ctx->Vf, &ctx->Vf, &ctx->P ) );
Manuel Pégourié-Gonnard15d5de12013-09-17 11:34:11 +0200395
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200396 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 +0200397
Manuel Pégourié-Gonnard143b5022013-09-04 16:29:59 +0200398cleanup:
Manuel Pégourié-Gonnardaf721672020-06-25 12:47:22 +0200399 mbedtls_mpi_free( &R );
400
Manuel Pégourié-Gonnard143b5022013-09-04 16:29:59 +0200401 return( ret );
402}
403
404/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000405 * Derive and export the shared secret (G^Y)^X mod P
406 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200407int mbedtls_dhm_calc_secret( mbedtls_dhm_context *ctx,
Manuel Pégourié-Gonnard33352052015-06-02 16:17:08 +0100408 unsigned char *output, size_t output_size, size_t *olen,
Manuel Pégourié-Gonnard2d627642013-09-04 14:22:07 +0200409 int (*f_rng)(void *, unsigned char *, size_t),
410 void *p_rng )
Paul Bakker5121ce52009-01-03 21:22:43 +0000411{
Janos Follath24eed8d2019-11-22 13:21:35 +0000412 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200413 mbedtls_mpi GYb;
Manuel Pégourié-Gonnard2d627642013-09-04 14:22:07 +0200414
Manuel Pégourié-Gonnard1a877222021-06-15 11:29:26 +0200415 if( f_rng == NULL )
416 return( MBEDTLS_ERR_DHM_BAD_INPUT_DATA );
417
Gilles Peskine487bbf62021-05-27 22:17:07 +0200418 if( output_size < mbedtls_dhm_get_len( ctx ) )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200419 return( MBEDTLS_ERR_DHM_BAD_INPUT_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +0000420
Paul Bakker345a6fe2011-02-28 21:20:02 +0000421 if( ( ret = dhm_check_range( &ctx->GY, &ctx->P ) ) != 0 )
Paul Bakkerc47840e2011-02-20 16:37:30 +0000422 return( ret );
423
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200424 mbedtls_mpi_init( &GYb );
Manuel Pégourié-Gonnard143b5022013-09-04 16:29:59 +0200425
426 /* Blind peer's value */
Manuel Pégourié-Gonnard1a877222021-06-15 11:29:26 +0200427 MBEDTLS_MPI_CHK( dhm_update_blinding( ctx, f_rng, p_rng ) );
428 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &GYb, &ctx->GY, &ctx->Vi ) );
429 MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &GYb, &GYb, &ctx->P ) );
Manuel Pégourié-Gonnard143b5022013-09-04 16:29:59 +0200430
431 /* Do modular exponentiation */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200432 MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &ctx->K, &GYb, &ctx->X,
Manuel Pégourié-Gonnard143b5022013-09-04 16:29:59 +0200433 &ctx->P, &ctx->RP ) );
434
435 /* Unblind secret value */
Manuel Pégourié-Gonnard1a877222021-06-15 11:29:26 +0200436 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &ctx->K, &ctx->K, &ctx->Vf ) );
437 MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &ctx->K, &ctx->K, &ctx->P ) );
Manuel Pégourié-Gonnard143b5022013-09-04 16:29:59 +0200438
Gilles Peskine03299dc2021-04-13 22:10:24 +0200439 /* Output the secret without any leading zero byte. This is mandatory
440 * for TLS per RFC 5246 §8.1.2. */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200441 *olen = mbedtls_mpi_size( &ctx->K );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200442 MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &ctx->K, output, *olen ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000443
444cleanup:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200445 mbedtls_mpi_free( &GYb );
Paul Bakker5121ce52009-01-03 21:22:43 +0000446
447 if( ret != 0 )
Chris Jones9f7a6932021-04-14 12:12:09 +0100448 return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_DHM_CALC_SECRET_FAILED, ret ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000449
450 return( 0 );
451}
452
453/*
454 * Free the components of a DHM key
455 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200456void mbedtls_dhm_free( mbedtls_dhm_context *ctx )
Paul Bakker5121ce52009-01-03 21:22:43 +0000457{
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500458 if( ctx == NULL )
459 return;
460
461 mbedtls_mpi_free( &ctx->pX );
462 mbedtls_mpi_free( &ctx->Vf );
463 mbedtls_mpi_free( &ctx->Vi );
464 mbedtls_mpi_free( &ctx->RP );
465 mbedtls_mpi_free( &ctx->K );
466 mbedtls_mpi_free( &ctx->GY );
467 mbedtls_mpi_free( &ctx->GX );
468 mbedtls_mpi_free( &ctx->X );
469 mbedtls_mpi_free( &ctx->G );
470 mbedtls_mpi_free( &ctx->P );
Manuel Pégourié-Gonnardb72b4ed2013-09-13 13:55:26 +0200471
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500472 mbedtls_platform_zeroize( ctx, sizeof( mbedtls_dhm_context ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000473}
474
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200475#if defined(MBEDTLS_ASN1_PARSE_C)
Paul Bakker40ce79f2013-09-15 17:43:54 +0200476/*
477 * Parse DHM parameters
478 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200479int mbedtls_dhm_parse_dhm( mbedtls_dhm_context *dhm, const unsigned char *dhmin,
Paul Bakkerb9e4e2c2014-05-01 14:18:25 +0200480 size_t dhminlen )
Paul Bakker40ce79f2013-09-15 17:43:54 +0200481{
Janos Follath24eed8d2019-11-22 13:21:35 +0000482 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker40ce79f2013-09-15 17:43:54 +0200483 size_t len;
484 unsigned char *p, *end;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200485#if defined(MBEDTLS_PEM_PARSE_C)
486 mbedtls_pem_context pem;
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500487#endif /* MBEDTLS_PEM_PARSE_C */
Paul Bakker40ce79f2013-09-15 17:43:54 +0200488
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500489#if defined(MBEDTLS_PEM_PARSE_C)
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200490 mbedtls_pem_init( &pem );
Paul Bakker40ce79f2013-09-15 17:43:54 +0200491
Manuel Pégourié-Gonnard43b37cb2015-05-12 11:20:10 +0200492 /* Avoid calling mbedtls_pem_read_buffer() on non-null-terminated string */
Manuel Pégourié-Gonnard0ece0f92015-05-12 12:43:54 +0200493 if( dhminlen == 0 || dhmin[dhminlen - 1] != '\0' )
Manuel Pégourié-Gonnard43b37cb2015-05-12 11:20:10 +0200494 ret = MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT;
495 else
496 ret = mbedtls_pem_read_buffer( &pem,
497 "-----BEGIN DH PARAMETERS-----",
498 "-----END DH PARAMETERS-----",
499 dhmin, NULL, 0, &dhminlen );
Paul Bakker40ce79f2013-09-15 17:43:54 +0200500
501 if( ret == 0 )
502 {
503 /*
504 * Was PEM encoded
505 */
506 dhminlen = pem.buflen;
507 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200508 else if( ret != MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
Paul Bakker40ce79f2013-09-15 17:43:54 +0200509 goto exit;
510
511 p = ( ret == 0 ) ? pem.buf : (unsigned char *) dhmin;
512#else
513 p = (unsigned char *) dhmin;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200514#endif /* MBEDTLS_PEM_PARSE_C */
Paul Bakker40ce79f2013-09-15 17:43:54 +0200515 end = p + dhminlen;
516
517 /*
518 * DHParams ::= SEQUENCE {
Daniel Kahn Gillmor2ed81732015-04-03 13:09:24 -0400519 * prime INTEGER, -- P
520 * generator INTEGER, -- g
521 * privateValueLength INTEGER OPTIONAL
Paul Bakker40ce79f2013-09-15 17:43:54 +0200522 * }
523 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200524 if( ( ret = mbedtls_asn1_get_tag( &p, end, &len,
525 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
Paul Bakker40ce79f2013-09-15 17:43:54 +0200526 {
Chris Jones9f7a6932021-04-14 12:12:09 +0100527 ret = MBEDTLS_ERROR_ADD( MBEDTLS_ERR_DHM_INVALID_FORMAT, ret );
Paul Bakker40ce79f2013-09-15 17:43:54 +0200528 goto exit;
529 }
530
531 end = p + len;
532
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200533 if( ( ret = mbedtls_asn1_get_mpi( &p, end, &dhm->P ) ) != 0 ||
534 ( ret = mbedtls_asn1_get_mpi( &p, end, &dhm->G ) ) != 0 )
Paul Bakker40ce79f2013-09-15 17:43:54 +0200535 {
Chris Jones9f7a6932021-04-14 12:12:09 +0100536 ret = MBEDTLS_ERROR_ADD( MBEDTLS_ERR_DHM_INVALID_FORMAT, ret );
Paul Bakker40ce79f2013-09-15 17:43:54 +0200537 goto exit;
538 }
539
540 if( p != end )
541 {
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;
545 mbedtls_mpi_init( &rec );
546 ret = mbedtls_asn1_get_mpi( &p, end, &rec );
547 mbedtls_mpi_free( &rec );
Daniel Kahn Gillmor2ed81732015-04-03 13:09:24 -0400548 if ( ret != 0 )
549 {
Chris Jones9f7a6932021-04-14 12:12:09 +0100550 ret = MBEDTLS_ERROR_ADD( MBEDTLS_ERR_DHM_INVALID_FORMAT, ret );
Daniel Kahn Gillmor2ed81732015-04-03 13:09:24 -0400551 goto exit;
552 }
553 if ( p != end )
554 {
Chris Jones9f7a6932021-04-14 12:12:09 +0100555 ret = MBEDTLS_ERROR_ADD( MBEDTLS_ERR_DHM_INVALID_FORMAT,
556 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
Daniel Kahn Gillmor2ed81732015-04-03 13:09:24 -0400557 goto exit;
558 }
Paul Bakker40ce79f2013-09-15 17:43:54 +0200559 }
560
561 ret = 0;
562
563exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200564#if defined(MBEDTLS_PEM_PARSE_C)
565 mbedtls_pem_free( &pem );
Paul Bakker40ce79f2013-09-15 17:43:54 +0200566#endif
567 if( ret != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200568 mbedtls_dhm_free( dhm );
Paul Bakker40ce79f2013-09-15 17:43:54 +0200569
570 return( ret );
571}
572
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200573#if defined(MBEDTLS_FS_IO)
Paul Bakker40ce79f2013-09-15 17:43:54 +0200574/*
575 * Load all data from a file into a given buffer.
Manuel Pégourié-Gonnard43b37cb2015-05-12 11:20:10 +0200576 *
577 * The file is expected to contain either PEM or DER encoded data.
578 * A terminating null byte is always appended. It is included in the announced
579 * length only if the data looks like it is PEM encoded.
Paul Bakker40ce79f2013-09-15 17:43:54 +0200580 */
581static int load_file( const char *path, unsigned char **buf, size_t *n )
582{
583 FILE *f;
584 long size;
585
586 if( ( f = fopen( path, "rb" ) ) == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200587 return( MBEDTLS_ERR_DHM_FILE_IO_ERROR );
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
590 fseek( f, 0, SEEK_END );
591 if( ( size = ftell( f ) ) == -1 )
592 {
593 fclose( f );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200594 return( MBEDTLS_ERR_DHM_FILE_IO_ERROR );
Paul Bakker40ce79f2013-09-15 17:43:54 +0200595 }
596 fseek( f, 0, SEEK_SET );
597
598 *n = (size_t) size;
599
600 if( *n + 1 == 0 ||
Manuel Pégourié-Gonnard7551cb92015-05-26 16:04:06 +0200601 ( *buf = mbedtls_calloc( 1, *n + 1 ) ) == NULL )
Paul Bakker40ce79f2013-09-15 17:43:54 +0200602 {
603 fclose( f );
Manuel Pégourié-Gonnard6a8ca332015-05-28 09:33:39 +0200604 return( MBEDTLS_ERR_DHM_ALLOC_FAILED );
Paul Bakker40ce79f2013-09-15 17:43:54 +0200605 }
606
607 if( fread( *buf, 1, *n, f ) != *n )
608 {
609 fclose( f );
Andres Amaya Garciabdbca7b2017-06-23 16:23:21 +0100610
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500611 mbedtls_platform_zeroize( *buf, *n + 1 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200612 mbedtls_free( *buf );
Andres Amaya Garciabdbca7b2017-06-23 16:23:21 +0100613
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200614 return( MBEDTLS_ERR_DHM_FILE_IO_ERROR );
Paul Bakker40ce79f2013-09-15 17:43:54 +0200615 }
616
617 fclose( f );
618
619 (*buf)[*n] = '\0';
620
Manuel Pégourié-Gonnard43b37cb2015-05-12 11:20:10 +0200621 if( strstr( (const char *) *buf, "-----BEGIN " ) != NULL )
622 ++*n;
623
Paul Bakker40ce79f2013-09-15 17:43:54 +0200624 return( 0 );
625}
626
627/*
628 * Load and parse DHM parameters
629 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200630int mbedtls_dhm_parse_dhmfile( mbedtls_dhm_context *dhm, const char *path )
Paul Bakker40ce79f2013-09-15 17:43:54 +0200631{
Janos Follath24eed8d2019-11-22 13:21:35 +0000632 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker40ce79f2013-09-15 17:43:54 +0200633 size_t n;
634 unsigned char *buf;
635
Paul Bakker66d5d072014-06-17 16:39:18 +0200636 if( ( ret = load_file( path, &buf, &n ) ) != 0 )
Paul Bakker40ce79f2013-09-15 17:43:54 +0200637 return( ret );
638
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200639 ret = mbedtls_dhm_parse_dhm( dhm, buf, n );
Paul Bakker40ce79f2013-09-15 17:43:54 +0200640
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500641 mbedtls_platform_zeroize( buf, n );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200642 mbedtls_free( buf );
Paul Bakker40ce79f2013-09-15 17:43:54 +0200643
644 return( ret );
645}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200646#endif /* MBEDTLS_FS_IO */
647#endif /* MBEDTLS_ASN1_PARSE_C */
nirekh0149762fa2017-12-25 06:46:48 +0000648#endif /* MBEDTLS_DHM_ALT */
Paul Bakker40ce79f2013-09-15 17:43:54 +0200649
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200650#if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +0000651
Hanno Becker8b0f9e62019-05-31 17:28:59 +0100652#if defined(MBEDTLS_PEM_PARSE_C)
Manuel Pégourié-Gonnard53585ee2015-06-25 08:52:25 +0200653static const char mbedtls_test_dhm_params[] =
654"-----BEGIN DH PARAMETERS-----\r\n"
655"MIGHAoGBAJ419DBEOgmQTzo5qXl5fQcN9TN455wkOL7052HzxxRVMyhYmwQcgJvh\r\n"
656"1sa18fyfR9OiVEMYglOpkqVoGLN7qd5aQNNi5W7/C+VBdHTBJcGZJyyP5B3qcz32\r\n"
657"9mLJKudlVudV0Qxk5qUJaPZ/xupz0NyoVpviuiBOI1gNi8ovSXWzAgEC\r\n"
658"-----END DH PARAMETERS-----\r\n";
Hanno Becker8b0f9e62019-05-31 17:28:59 +0100659#else /* MBEDTLS_PEM_PARSE_C */
660static const char mbedtls_test_dhm_params[] = {
661 0x30, 0x81, 0x87, 0x02, 0x81, 0x81, 0x00, 0x9e, 0x35, 0xf4, 0x30, 0x44,
662 0x3a, 0x09, 0x90, 0x4f, 0x3a, 0x39, 0xa9, 0x79, 0x79, 0x7d, 0x07, 0x0d,
663 0xf5, 0x33, 0x78, 0xe7, 0x9c, 0x24, 0x38, 0xbe, 0xf4, 0xe7, 0x61, 0xf3,
664 0xc7, 0x14, 0x55, 0x33, 0x28, 0x58, 0x9b, 0x04, 0x1c, 0x80, 0x9b, 0xe1,
665 0xd6, 0xc6, 0xb5, 0xf1, 0xfc, 0x9f, 0x47, 0xd3, 0xa2, 0x54, 0x43, 0x18,
666 0x82, 0x53, 0xa9, 0x92, 0xa5, 0x68, 0x18, 0xb3, 0x7b, 0xa9, 0xde, 0x5a,
667 0x40, 0xd3, 0x62, 0xe5, 0x6e, 0xff, 0x0b, 0xe5, 0x41, 0x74, 0x74, 0xc1,
668 0x25, 0xc1, 0x99, 0x27, 0x2c, 0x8f, 0xe4, 0x1d, 0xea, 0x73, 0x3d, 0xf6,
669 0xf6, 0x62, 0xc9, 0x2a, 0xe7, 0x65, 0x56, 0xe7, 0x55, 0xd1, 0x0c, 0x64,
670 0xe6, 0xa5, 0x09, 0x68, 0xf6, 0x7f, 0xc6, 0xea, 0x73, 0xd0, 0xdc, 0xa8,
671 0x56, 0x9b, 0xe2, 0xba, 0x20, 0x4e, 0x23, 0x58, 0x0d, 0x8b, 0xca, 0x2f,
672 0x49, 0x75, 0xb3, 0x02, 0x01, 0x02 };
673#endif /* MBEDTLS_PEM_PARSE_C */
Manuel Pégourié-Gonnard53585ee2015-06-25 08:52:25 +0200674
675static const size_t mbedtls_test_dhm_params_len = sizeof( mbedtls_test_dhm_params );
Paul Bakker40ce79f2013-09-15 17:43:54 +0200676
Paul Bakker5121ce52009-01-03 21:22:43 +0000677/*
678 * Checkup routine
679 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200680int mbedtls_dhm_self_test( int verbose )
Paul Bakker5121ce52009-01-03 21:22:43 +0000681{
Janos Follath24eed8d2019-11-22 13:21:35 +0000682 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200683 mbedtls_dhm_context dhm;
Paul Bakker40ce79f2013-09-15 17:43:54 +0200684
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200685 mbedtls_dhm_init( &dhm );
Paul Bakker8f870b02014-06-20 13:32:38 +0200686
Paul Bakker40ce79f2013-09-15 17:43:54 +0200687 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200688 mbedtls_printf( " DHM parameter load: " );
Paul Bakker40ce79f2013-09-15 17:43:54 +0200689
Manuel Pégourié-Gonnard53585ee2015-06-25 08:52:25 +0200690 if( ( ret = mbedtls_dhm_parse_dhm( &dhm,
691 (const unsigned char *) mbedtls_test_dhm_params,
692 mbedtls_test_dhm_params_len ) ) != 0 )
Paul Bakker40ce79f2013-09-15 17:43:54 +0200693 {
694 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200695 mbedtls_printf( "failed\n" );
Paul Bakker40ce79f2013-09-15 17:43:54 +0200696
Manuel Pégourié-Gonnardb196fc22014-07-09 16:53:29 +0200697 ret = 1;
Paul Bakker8f870b02014-06-20 13:32:38 +0200698 goto exit;
Paul Bakker40ce79f2013-09-15 17:43:54 +0200699 }
700
701 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200702 mbedtls_printf( "passed\n\n" );
Paul Bakker40ce79f2013-09-15 17:43:54 +0200703
Paul Bakker8f870b02014-06-20 13:32:38 +0200704exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200705 mbedtls_dhm_free( &dhm );
Paul Bakker40ce79f2013-09-15 17:43:54 +0200706
Paul Bakker8f870b02014-06-20 13:32:38 +0200707 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 */