blob: c01388e7127be50c22921953f0010404d67d9070 [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
Andrzej Kurekc470b6b2019-01-31 08:20:20 -050050#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 )
54
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 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020058static int dhm_read_bignum( mbedtls_mpi *X,
Paul Bakker5121ce52009-01-03 21:22:43 +000059 unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +000060 const unsigned char *end )
Paul Bakker5121ce52009-01-03 21:22:43 +000061{
62 int ret, n;
63
64 if( end - *p < 2 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020065 return( MBEDTLS_ERR_DHM_BAD_INPUT_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +000066
67 n = ( (*p)[0] << 8 ) | (*p)[1];
68 (*p) += 2;
69
70 if( (int)( end - *p ) < n )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020071 return( MBEDTLS_ERR_DHM_BAD_INPUT_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +000072
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020073 if( ( ret = mbedtls_mpi_read_binary( X, *p, n ) ) != 0 )
Chris Jones9f7a6932021-04-14 12:12:09 +010074 return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_DHM_READ_PARAMS_FAILED, ret ) );
Paul Bakker5121ce52009-01-03 21:22:43 +000075
76 (*p) += n;
77
78 return( 0 );
79}
80
81/*
Paul Bakkeraec37cb2012-04-26 18:59:59 +000082 * Verify sanity of parameter with regards to P
Paul Bakker345a6fe2011-02-28 21:20:02 +000083 *
Paul Bakkeraec37cb2012-04-26 18:59:59 +000084 * Parameter should be: 2 <= public_param <= P - 2
Paul Bakker345a6fe2011-02-28 21:20:02 +000085 *
Janos Follathaa325d72017-09-20 15:33:24 +010086 * This means that we need to return an error if
Janos Follath1ad1c6d2017-09-21 09:02:11 +010087 * public_param < 2 or public_param > P-2
Janos Follathaa325d72017-09-20 15:33:24 +010088 *
Paul Bakker345a6fe2011-02-28 21:20:02 +000089 * For more information on the attack, see:
90 * http://www.cl.cam.ac.uk/~rja14/Papers/psandqs.pdf
91 * http://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2005-2643
Paul Bakkerc47840e2011-02-20 16:37:30 +000092 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020093static int dhm_check_range( const mbedtls_mpi *param, const mbedtls_mpi *P )
Paul Bakkerc47840e2011-02-20 16:37:30 +000094{
Gilles Peskine8e38acc2021-03-31 22:56:43 +020095 mbedtls_mpi U;
Janos Follathaa325d72017-09-20 15:33:24 +010096 int ret = 0;
Paul Bakkerc47840e2011-02-20 16:37:30 +000097
Gilles Peskine8e38acc2021-03-31 22:56:43 +020098 mbedtls_mpi_init( &U );
Paul Bakker3d8fb632014-04-17 12:42:41 +020099
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200100 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &U, P, 2 ) );
Paul Bakkerc47840e2011-02-20 16:37:30 +0000101
Gilles Peskine8e38acc2021-03-31 22:56:43 +0200102 if( mbedtls_mpi_cmp_int( param, 2 ) < 0 ||
Janos Follathaa325d72017-09-20 15:33:24 +0100103 mbedtls_mpi_cmp_mpi( param, &U ) > 0 )
Paul Bakkerc47840e2011-02-20 16:37:30 +0000104 {
Janos Follathaa325d72017-09-20 15:33:24 +0100105 ret = MBEDTLS_ERR_DHM_BAD_INPUT_DATA;
Paul Bakkerc47840e2011-02-20 16:37:30 +0000106 }
107
Paul Bakker3d8fb632014-04-17 12:42:41 +0200108cleanup:
Gilles Peskine8e38acc2021-03-31 22:56:43 +0200109 mbedtls_mpi_free( &U );
Paul Bakker345a6fe2011-02-28 21:20:02 +0000110 return( ret );
Paul Bakkerc47840e2011-02-20 16:37:30 +0000111}
112
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200113void mbedtls_dhm_init( mbedtls_dhm_context *ctx )
Paul Bakker8f870b02014-06-20 13:32:38 +0200114{
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500115 DHM_VALIDATE( ctx != NULL );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200116 memset( ctx, 0, sizeof( mbedtls_dhm_context ) );
Paul Bakker8f870b02014-06-20 13:32:38 +0200117}
118
Gilles Peskine487bbf62021-05-27 22:17:07 +0200119size_t mbedtls_dhm_get_bitlen( const mbedtls_dhm_context *ctx )
120{
121 return( mbedtls_mpi_bitlen( &ctx->P ) );
122}
123
124size_t mbedtls_dhm_get_len( const mbedtls_dhm_context *ctx )
125{
126 return( mbedtls_mpi_size( &ctx->P ) );
127}
128
Gilles Peskinee5702482021-06-11 21:59:08 +0200129int mbedtls_dhm_get_value( const mbedtls_dhm_context *ctx,
130 mbedtls_dhm_parameter param,
131 mbedtls_mpi *dest )
Gilles Peskine71acc6e2021-05-27 22:50:53 +0200132{
133 const mbedtls_mpi *src = NULL;
134 switch( param )
135 {
136 case MBEDTLS_DHM_PARAM_P:
137 src = &ctx->P;
138 break;
139 case MBEDTLS_DHM_PARAM_G:
140 src = &ctx->G;
141 break;
142 case MBEDTLS_DHM_PARAM_X:
143 src = &ctx->X;
144 break;
145 case MBEDTLS_DHM_PARAM_GX:
146 src = &ctx->GX;
147 break;
148 case MBEDTLS_DHM_PARAM_GY:
149 src = &ctx->GY;
150 break;
151 case MBEDTLS_DHM_PARAM_K:
152 src = &ctx->K;
153 break;
154 default:
155 return( MBEDTLS_ERR_DHM_BAD_INPUT_DATA );
156 }
157 return( mbedtls_mpi_copy( dest, src ) );
158}
159
Paul Bakkerc47840e2011-02-20 16:37:30 +0000160/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000161 * Parse the ServerKeyExchange parameters
162 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200163int mbedtls_dhm_read_params( mbedtls_dhm_context *ctx,
Paul Bakker5121ce52009-01-03 21:22:43 +0000164 unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000165 const unsigned char *end )
Paul Bakker5121ce52009-01-03 21:22:43 +0000166{
Janos Follath24eed8d2019-11-22 13:21:35 +0000167 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500168 DHM_VALIDATE_RET( ctx != NULL );
169 DHM_VALIDATE_RET( p != NULL && *p != NULL );
170 DHM_VALIDATE_RET( end != NULL );
Paul Bakker5121ce52009-01-03 21:22:43 +0000171
Paul Bakker5121ce52009-01-03 21:22:43 +0000172 if( ( ret = dhm_read_bignum( &ctx->P, p, end ) ) != 0 ||
173 ( ret = dhm_read_bignum( &ctx->G, p, end ) ) != 0 ||
174 ( ret = dhm_read_bignum( &ctx->GY, p, end ) ) != 0 )
175 return( ret );
176
Paul Bakker345a6fe2011-02-28 21:20:02 +0000177 if( ( ret = dhm_check_range( &ctx->GY, &ctx->P ) ) != 0 )
178 return( ret );
179
Paul Bakker5121ce52009-01-03 21:22:43 +0000180 return( 0 );
181}
182
Gilles Peskine17f1a262021-03-31 22:48:14 +0200183/*
Gilles Peskineda7ee012021-03-31 23:04:50 +0200184 * Pick a random R in the range [2, M-2] for blinding or key generation.
Gilles Peskine17f1a262021-03-31 22:48:14 +0200185 */
186static int dhm_random_below( mbedtls_mpi *R, const mbedtls_mpi *M,
187 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
188{
Gilles Peskineda7ee012021-03-31 23:04:50 +0200189 int ret;
Gilles Peskine17f1a262021-03-31 22:48:14 +0200190
Gilles Peskineda7ee012021-03-31 23:04:50 +0200191 MBEDTLS_MPI_CHK( mbedtls_mpi_random( R, 3, M, f_rng, p_rng ) );
192 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( R, R, 1 ) );
Gilles Peskine17f1a262021-03-31 22:48:14 +0200193
194cleanup:
195 return( ret );
196}
197
Gilles Peskinecb660f22021-03-31 22:35:13 +0200198static int dhm_make_common( mbedtls_dhm_context *ctx, int x_size,
199 int (*f_rng)(void *, unsigned char *, size_t),
200 void *p_rng )
Paul Bakker5121ce52009-01-03 21:22:43 +0000201{
Gilles Peskine17f1a262021-03-31 22:48:14 +0200202 int ret = 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000203
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200204 if( mbedtls_mpi_cmp_int( &ctx->P, 0 ) == 0 )
205 return( MBEDTLS_ERR_DHM_BAD_INPUT_DATA );
Gilles Peskine17f1a262021-03-31 22:48:14 +0200206 if( x_size < 0 )
207 return( MBEDTLS_ERR_DHM_BAD_INPUT_DATA );
Paul Bakkerb5b20f12012-09-16 15:07:49 +0000208
Gilles Peskine17f1a262021-03-31 22:48:14 +0200209 if( (unsigned) x_size < mbedtls_mpi_size( &ctx->P ) )
Paul Bakkeraec37cb2012-04-26 18:59:59 +0000210 {
Ron Eldor7269fee2017-01-12 14:50:50 +0200211 MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( &ctx->X, x_size, f_rng, p_rng ) );
Paul Bakkeraec37cb2012-04-26 18:59:59 +0000212 }
Gilles Peskine17f1a262021-03-31 22:48:14 +0200213 else
214 {
215 /* Generate X as large as possible ( <= P - 2 ) */
216 ret = dhm_random_below( &ctx->X, &ctx->P, f_rng, p_rng );
217 if( ret == MBEDTLS_ERR_MPI_NOT_ACCEPTABLE )
218 return( MBEDTLS_ERR_DHM_MAKE_PARAMS_FAILED );
219 if( ret != 0 )
220 return( ret );
221 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000222
Paul Bakkerff7fe672010-07-18 09:45:05 +0000223 /*
224 * Calculate GX = G^X mod P
225 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200226 MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &ctx->GX, &ctx->G, &ctx->X,
Paul Bakker5121ce52009-01-03 21:22:43 +0000227 &ctx->P , &ctx->RP ) );
228
Paul Bakker345a6fe2011-02-28 21:20:02 +0000229 if( ( ret = dhm_check_range( &ctx->GX, &ctx->P ) ) != 0 )
Paul Bakkerc47840e2011-02-20 16:37:30 +0000230 return( ret );
231
Gilles Peskinecb660f22021-03-31 22:35:13 +0200232cleanup:
233 return( ret );
234}
235
236/*
237 * Setup and write the ServerKeyExchange parameters
238 */
239int mbedtls_dhm_make_params( mbedtls_dhm_context *ctx, int x_size,
240 unsigned char *output, size_t *olen,
241 int (*f_rng)(void *, unsigned char *, size_t),
242 void *p_rng )
243{
244 int ret;
245 size_t n1, n2, n3;
246 unsigned char *p;
247 DHM_VALIDATE_RET( ctx != NULL );
248 DHM_VALIDATE_RET( output != NULL );
249 DHM_VALIDATE_RET( olen != NULL );
250 DHM_VALIDATE_RET( f_rng != NULL );
251
252 ret = dhm_make_common( ctx, x_size, f_rng, p_rng );
253 if( ret != 0 )
254 goto cleanup;
255
Paul Bakker5121ce52009-01-03 21:22:43 +0000256 /*
Gilles Peskine03299dc2021-04-13 22:10:24 +0200257 * Export P, G, GX. RFC 5246 §4.4 states that "leading zero octets are
258 * not required". We omit leading zeros for compactness.
Paul Bakker5121ce52009-01-03 21:22:43 +0000259 */
Hanno Beckerde6c1642017-10-02 15:03:15 +0100260#define DHM_MPI_EXPORT( X, n ) \
Hanno Beckere71ad122017-09-28 10:32:25 +0100261 do { \
Hanno Beckerde6c1642017-10-02 15:03:15 +0100262 MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( ( X ), \
263 p + 2, \
264 ( n ) ) ); \
Joe Subbianifbeb6922021-07-16 14:27:50 +0100265 *p++ = MBEDTLS_BYTE_1( n ); \
266 *p++ = MBEDTLS_BYTE_0( n ); \
Hanno Beckerde6c1642017-10-02 15:03:15 +0100267 p += ( n ); \
Hanno Beckere71ad122017-09-28 10:32:25 +0100268 } while( 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000269
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200270 n1 = mbedtls_mpi_size( &ctx->P );
271 n2 = mbedtls_mpi_size( &ctx->G );
272 n3 = mbedtls_mpi_size( &ctx->GX );
Paul Bakker5121ce52009-01-03 21:22:43 +0000273
274 p = output;
275 DHM_MPI_EXPORT( &ctx->P , n1 );
276 DHM_MPI_EXPORT( &ctx->G , n2 );
277 DHM_MPI_EXPORT( &ctx->GX, n3 );
278
Hanno Beckere71ad122017-09-28 10:32:25 +0100279 *olen = p - output;
Paul Bakker5121ce52009-01-03 21:22:43 +0000280
Paul Bakker5121ce52009-01-03 21:22:43 +0000281cleanup:
Gilles Peskinecb660f22021-03-31 22:35:13 +0200282 if( ret != 0 && ret > -128 )
283 ret = MBEDTLS_ERROR_ADD( MBEDTLS_ERR_DHM_MAKE_PARAMS_FAILED, ret );
284 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000285}
286
287/*
Hanno Becker8880e752017-10-04 13:15:08 +0100288 * Set prime modulus and generator
289 */
290int mbedtls_dhm_set_group( mbedtls_dhm_context *ctx,
291 const mbedtls_mpi *P,
292 const mbedtls_mpi *G )
293{
Janos Follath24eed8d2019-11-22 13:21:35 +0000294 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500295 DHM_VALIDATE_RET( ctx != NULL );
296 DHM_VALIDATE_RET( P != NULL );
297 DHM_VALIDATE_RET( G != NULL );
Hanno Becker8880e752017-10-04 13:15:08 +0100298
299 if( ( ret = mbedtls_mpi_copy( &ctx->P, P ) ) != 0 ||
300 ( ret = mbedtls_mpi_copy( &ctx->G, G ) ) != 0 )
301 {
Chris Jones9f7a6932021-04-14 12:12:09 +0100302 return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_DHM_SET_GROUP_FAILED, ret ) );
Hanno Becker8880e752017-10-04 13:15:08 +0100303 }
304
Hanno Becker8880e752017-10-04 13:15:08 +0100305 return( 0 );
306}
307
308/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000309 * Import the peer's public value G^Y
310 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200311int mbedtls_dhm_read_public( mbedtls_dhm_context *ctx,
Paul Bakker23986e52011-04-24 08:57:21 +0000312 const unsigned char *input, size_t ilen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000313{
Janos Follath24eed8d2019-11-22 13:21:35 +0000314 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500315 DHM_VALIDATE_RET( ctx != NULL );
316 DHM_VALIDATE_RET( input != NULL );
Paul Bakker5121ce52009-01-03 21:22:43 +0000317
Gilles Peskine487bbf62021-05-27 22:17:07 +0200318 if( ilen < 1 || ilen > mbedtls_dhm_get_len( ctx ) )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200319 return( MBEDTLS_ERR_DHM_BAD_INPUT_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +0000320
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200321 if( ( ret = mbedtls_mpi_read_binary( &ctx->GY, input, ilen ) ) != 0 )
Chris Jones9f7a6932021-04-14 12:12:09 +0100322 return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_DHM_READ_PUBLIC_FAILED, ret ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000323
324 return( 0 );
325}
326
327/*
328 * Create own private value X and export G^X
329 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200330int mbedtls_dhm_make_public( mbedtls_dhm_context *ctx, int x_size,
Paul Bakker23986e52011-04-24 08:57:21 +0000331 unsigned char *output, size_t olen,
Paul Bakkera3d195c2011-11-27 21:07:34 +0000332 int (*f_rng)(void *, unsigned char *, size_t),
333 void *p_rng )
Paul Bakker5121ce52009-01-03 21:22:43 +0000334{
Gilles Peskinecb660f22021-03-31 22:35:13 +0200335 int ret;
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500336 DHM_VALIDATE_RET( ctx != NULL );
337 DHM_VALIDATE_RET( output != NULL );
338 DHM_VALIDATE_RET( f_rng != NULL );
Paul Bakker5121ce52009-01-03 21:22:43 +0000339
Gilles Peskine487bbf62021-05-27 22:17:07 +0200340 if( olen < 1 || olen > mbedtls_dhm_get_len( ctx ) )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200341 return( MBEDTLS_ERR_DHM_BAD_INPUT_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +0000342
Gilles Peskinecb660f22021-03-31 22:35:13 +0200343 ret = dhm_make_common( ctx, x_size, f_rng, p_rng );
344 if( ret == MBEDTLS_ERR_DHM_MAKE_PARAMS_FAILED )
345 return( MBEDTLS_ERR_DHM_MAKE_PUBLIC_FAILED );
346 if( ret != 0 )
347 goto cleanup;
Paul Bakkerc47840e2011-02-20 16:37:30 +0000348
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200349 MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &ctx->GX, output, olen ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000350
351cleanup:
Gilles Peskinecb660f22021-03-31 22:35:13 +0200352 if( ret != 0 && ret > -128 )
353 ret = MBEDTLS_ERROR_ADD( MBEDTLS_ERR_DHM_MAKE_PUBLIC_FAILED, ret );
354 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000355}
356
Manuel Pégourié-Gonnard9f58c4b2020-06-25 12:34:58 +0200357
358/*
Manuel Pégourié-Gonnard143b5022013-09-04 16:29:59 +0200359 * Use the blinding method and optimisation suggested in section 10 of:
360 * KOCHER, Paul C. Timing attacks on implementations of Diffie-Hellman, RSA,
Manuel Pégourié-Gonnard998930a2015-04-03 13:48:06 +0200361 * DSS, and other systems. In : Advances in Cryptology-CRYPTO'96. Springer
Manuel Pégourié-Gonnard143b5022013-09-04 16:29:59 +0200362 * Berlin Heidelberg, 1996. p. 104-113.
363 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200364static int dhm_update_blinding( mbedtls_dhm_context *ctx,
Manuel Pégourié-Gonnard143b5022013-09-04 16:29:59 +0200365 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
366{
Manuel Pégourié-Gonnard9f58c4b2020-06-25 12:34:58 +0200367 int ret;
Manuel Pégourié-Gonnardaf721672020-06-25 12:47:22 +0200368 mbedtls_mpi R;
369
370 mbedtls_mpi_init( &R );
Manuel Pégourié-Gonnard143b5022013-09-04 16:29:59 +0200371
372 /*
Manuel Pégourié-Gonnard15d5de12013-09-17 11:34:11 +0200373 * Don't use any blinding the first time a particular X is used,
374 * but remember it to use blinding next time.
Manuel Pégourié-Gonnard143b5022013-09-04 16:29:59 +0200375 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200376 if( mbedtls_mpi_cmp_mpi( &ctx->X, &ctx->pX ) != 0 )
Manuel Pégourié-Gonnarded8a02b2013-09-04 16:39:03 +0200377 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200378 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &ctx->pX, &ctx->X ) );
379 MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &ctx->Vi, 1 ) );
380 MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &ctx->Vf, 1 ) );
Manuel Pégourié-Gonnarded8a02b2013-09-04 16:39:03 +0200381
Manuel Pégourié-Gonnard143b5022013-09-04 16:29:59 +0200382 return( 0 );
383 }
384
385 /*
Manuel Pégourié-Gonnard15d5de12013-09-17 11:34:11 +0200386 * Ok, we need blinding. Can we re-use existing values?
387 * If yes, just update them by squaring them.
Manuel Pégourié-Gonnard143b5022013-09-04 16:29:59 +0200388 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200389 if( mbedtls_mpi_cmp_int( &ctx->Vi, 1 ) != 0 )
Manuel Pégourié-Gonnard15d5de12013-09-17 11:34:11 +0200390 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200391 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &ctx->Vi, &ctx->Vi, &ctx->Vi ) );
392 MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &ctx->Vi, &ctx->Vi, &ctx->P ) );
Manuel Pégourié-Gonnard15d5de12013-09-17 11:34:11 +0200393
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200394 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &ctx->Vf, &ctx->Vf, &ctx->Vf ) );
395 MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &ctx->Vf, &ctx->Vf, &ctx->P ) );
Manuel Pégourié-Gonnard15d5de12013-09-17 11:34:11 +0200396
397 return( 0 );
398 }
399
400 /*
401 * We need to generate blinding values from scratch
402 */
403
Gilles Peskine7b2b66e2021-03-31 22:50:57 +0200404 /* Vi = random( 2, P-2 ) */
Manuel Pégourié-Gonnard9f58c4b2020-06-25 12:34:58 +0200405 MBEDTLS_MPI_CHK( dhm_random_below( &ctx->Vi, &ctx->P, f_rng, p_rng ) );
Manuel Pégourié-Gonnard15d5de12013-09-17 11:34:11 +0200406
Manuel Pégourié-Gonnardaf721672020-06-25 12:47:22 +0200407 /* Vf = Vi^-X mod P
408 * First compute Vi^-1 = R * (R Vi)^-1, (avoiding leaks from inv_mod),
409 * then elevate to the Xth power. */
410 MBEDTLS_MPI_CHK( dhm_random_below( &R, &ctx->P, f_rng, p_rng ) );
411 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &ctx->Vf, &ctx->Vi, &R ) );
412 MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &ctx->Vf, &ctx->Vf, &ctx->P ) );
413 MBEDTLS_MPI_CHK( mbedtls_mpi_inv_mod( &ctx->Vf, &ctx->Vf, &ctx->P ) );
414 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &ctx->Vf, &ctx->Vf, &R ) );
415 MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &ctx->Vf, &ctx->Vf, &ctx->P ) );
Manuel Pégourié-Gonnard15d5de12013-09-17 11:34:11 +0200416
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200417 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 +0200418
Manuel Pégourié-Gonnard143b5022013-09-04 16:29:59 +0200419cleanup:
Manuel Pégourié-Gonnardaf721672020-06-25 12:47:22 +0200420 mbedtls_mpi_free( &R );
421
Manuel Pégourié-Gonnard143b5022013-09-04 16:29:59 +0200422 return( ret );
423}
424
425/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000426 * Derive and export the shared secret (G^Y)^X mod P
427 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200428int mbedtls_dhm_calc_secret( mbedtls_dhm_context *ctx,
Manuel Pégourié-Gonnard33352052015-06-02 16:17:08 +0100429 unsigned char *output, size_t output_size, size_t *olen,
Manuel Pégourié-Gonnard2d627642013-09-04 14:22:07 +0200430 int (*f_rng)(void *, unsigned char *, size_t),
431 void *p_rng )
Paul Bakker5121ce52009-01-03 21:22:43 +0000432{
Janos Follath24eed8d2019-11-22 13:21:35 +0000433 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200434 mbedtls_mpi GYb;
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500435 DHM_VALIDATE_RET( ctx != NULL );
436 DHM_VALIDATE_RET( output != NULL );
437 DHM_VALIDATE_RET( olen != NULL );
Manuel Pégourié-Gonnard2d627642013-09-04 14:22:07 +0200438
Manuel Pégourié-Gonnard1a877222021-06-15 11:29:26 +0200439 if( f_rng == NULL )
440 return( MBEDTLS_ERR_DHM_BAD_INPUT_DATA );
441
Gilles Peskine487bbf62021-05-27 22:17:07 +0200442 if( output_size < mbedtls_dhm_get_len( ctx ) )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200443 return( MBEDTLS_ERR_DHM_BAD_INPUT_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +0000444
Paul Bakker345a6fe2011-02-28 21:20:02 +0000445 if( ( ret = dhm_check_range( &ctx->GY, &ctx->P ) ) != 0 )
Paul Bakkerc47840e2011-02-20 16:37:30 +0000446 return( ret );
447
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200448 mbedtls_mpi_init( &GYb );
Manuel Pégourié-Gonnard143b5022013-09-04 16:29:59 +0200449
450 /* Blind peer's value */
Manuel Pégourié-Gonnard1a877222021-06-15 11:29:26 +0200451 MBEDTLS_MPI_CHK( dhm_update_blinding( ctx, f_rng, p_rng ) );
452 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &GYb, &ctx->GY, &ctx->Vi ) );
453 MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &GYb, &GYb, &ctx->P ) );
Manuel Pégourié-Gonnard143b5022013-09-04 16:29:59 +0200454
455 /* Do modular exponentiation */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200456 MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &ctx->K, &GYb, &ctx->X,
Manuel Pégourié-Gonnard143b5022013-09-04 16:29:59 +0200457 &ctx->P, &ctx->RP ) );
458
459 /* Unblind secret value */
Manuel Pégourié-Gonnard1a877222021-06-15 11:29:26 +0200460 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &ctx->K, &ctx->K, &ctx->Vf ) );
461 MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &ctx->K, &ctx->K, &ctx->P ) );
Manuel Pégourié-Gonnard143b5022013-09-04 16:29:59 +0200462
Gilles Peskine03299dc2021-04-13 22:10:24 +0200463 /* Output the secret without any leading zero byte. This is mandatory
464 * for TLS per RFC 5246 §8.1.2. */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200465 *olen = mbedtls_mpi_size( &ctx->K );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200466 MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &ctx->K, output, *olen ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000467
468cleanup:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200469 mbedtls_mpi_free( &GYb );
Paul Bakker5121ce52009-01-03 21:22:43 +0000470
471 if( ret != 0 )
Chris Jones9f7a6932021-04-14 12:12:09 +0100472 return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_DHM_CALC_SECRET_FAILED, ret ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000473
474 return( 0 );
475}
476
477/*
478 * Free the components of a DHM key
479 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200480void mbedtls_dhm_free( mbedtls_dhm_context *ctx )
Paul Bakker5121ce52009-01-03 21:22:43 +0000481{
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500482 if( ctx == NULL )
483 return;
484
485 mbedtls_mpi_free( &ctx->pX );
486 mbedtls_mpi_free( &ctx->Vf );
487 mbedtls_mpi_free( &ctx->Vi );
488 mbedtls_mpi_free( &ctx->RP );
489 mbedtls_mpi_free( &ctx->K );
490 mbedtls_mpi_free( &ctx->GY );
491 mbedtls_mpi_free( &ctx->GX );
492 mbedtls_mpi_free( &ctx->X );
493 mbedtls_mpi_free( &ctx->G );
494 mbedtls_mpi_free( &ctx->P );
Manuel Pégourié-Gonnardb72b4ed2013-09-13 13:55:26 +0200495
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500496 mbedtls_platform_zeroize( ctx, sizeof( mbedtls_dhm_context ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000497}
498
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200499#if defined(MBEDTLS_ASN1_PARSE_C)
Paul Bakker40ce79f2013-09-15 17:43:54 +0200500/*
501 * Parse DHM parameters
502 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200503int mbedtls_dhm_parse_dhm( mbedtls_dhm_context *dhm, const unsigned char *dhmin,
Paul Bakkerb9e4e2c2014-05-01 14:18:25 +0200504 size_t dhminlen )
Paul Bakker40ce79f2013-09-15 17:43:54 +0200505{
Janos Follath24eed8d2019-11-22 13:21:35 +0000506 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker40ce79f2013-09-15 17:43:54 +0200507 size_t len;
508 unsigned char *p, *end;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200509#if defined(MBEDTLS_PEM_PARSE_C)
510 mbedtls_pem_context pem;
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500511#endif /* MBEDTLS_PEM_PARSE_C */
Paul Bakker40ce79f2013-09-15 17:43:54 +0200512
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500513 DHM_VALIDATE_RET( dhm != NULL );
514 DHM_VALIDATE_RET( dhmin != NULL );
515
516#if defined(MBEDTLS_PEM_PARSE_C)
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200517 mbedtls_pem_init( &pem );
Paul Bakker40ce79f2013-09-15 17:43:54 +0200518
Manuel Pégourié-Gonnard43b37cb2015-05-12 11:20:10 +0200519 /* Avoid calling mbedtls_pem_read_buffer() on non-null-terminated string */
Manuel Pégourié-Gonnard0ece0f92015-05-12 12:43:54 +0200520 if( dhminlen == 0 || dhmin[dhminlen - 1] != '\0' )
Manuel Pégourié-Gonnard43b37cb2015-05-12 11:20:10 +0200521 ret = MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT;
522 else
523 ret = mbedtls_pem_read_buffer( &pem,
524 "-----BEGIN DH PARAMETERS-----",
525 "-----END DH PARAMETERS-----",
526 dhmin, NULL, 0, &dhminlen );
Paul Bakker40ce79f2013-09-15 17:43:54 +0200527
528 if( ret == 0 )
529 {
530 /*
531 * Was PEM encoded
532 */
533 dhminlen = pem.buflen;
534 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200535 else if( ret != MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
Paul Bakker40ce79f2013-09-15 17:43:54 +0200536 goto exit;
537
538 p = ( ret == 0 ) ? pem.buf : (unsigned char *) dhmin;
539#else
540 p = (unsigned char *) dhmin;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200541#endif /* MBEDTLS_PEM_PARSE_C */
Paul Bakker40ce79f2013-09-15 17:43:54 +0200542 end = p + dhminlen;
543
544 /*
545 * DHParams ::= SEQUENCE {
Daniel Kahn Gillmor2ed81732015-04-03 13:09:24 -0400546 * prime INTEGER, -- P
547 * generator INTEGER, -- g
548 * privateValueLength INTEGER OPTIONAL
Paul Bakker40ce79f2013-09-15 17:43:54 +0200549 * }
550 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200551 if( ( ret = mbedtls_asn1_get_tag( &p, end, &len,
552 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
Paul Bakker40ce79f2013-09-15 17:43:54 +0200553 {
Chris Jones9f7a6932021-04-14 12:12:09 +0100554 ret = MBEDTLS_ERROR_ADD( MBEDTLS_ERR_DHM_INVALID_FORMAT, ret );
Paul Bakker40ce79f2013-09-15 17:43:54 +0200555 goto exit;
556 }
557
558 end = p + len;
559
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200560 if( ( ret = mbedtls_asn1_get_mpi( &p, end, &dhm->P ) ) != 0 ||
561 ( ret = mbedtls_asn1_get_mpi( &p, end, &dhm->G ) ) != 0 )
Paul Bakker40ce79f2013-09-15 17:43:54 +0200562 {
Chris Jones9f7a6932021-04-14 12:12:09 +0100563 ret = MBEDTLS_ERROR_ADD( MBEDTLS_ERR_DHM_INVALID_FORMAT, ret );
Paul Bakker40ce79f2013-09-15 17:43:54 +0200564 goto exit;
565 }
566
567 if( p != end )
568 {
Manuel Pégourié-Gonnardde9b3632015-04-17 20:06:31 +0200569 /* This might be the optional privateValueLength.
570 * If so, we can cleanly discard it */
571 mbedtls_mpi rec;
572 mbedtls_mpi_init( &rec );
573 ret = mbedtls_asn1_get_mpi( &p, end, &rec );
574 mbedtls_mpi_free( &rec );
Daniel Kahn Gillmor2ed81732015-04-03 13:09:24 -0400575 if ( ret != 0 )
576 {
Chris Jones9f7a6932021-04-14 12:12:09 +0100577 ret = MBEDTLS_ERROR_ADD( MBEDTLS_ERR_DHM_INVALID_FORMAT, ret );
Daniel Kahn Gillmor2ed81732015-04-03 13:09:24 -0400578 goto exit;
579 }
580 if ( p != end )
581 {
Chris Jones9f7a6932021-04-14 12:12:09 +0100582 ret = MBEDTLS_ERROR_ADD( MBEDTLS_ERR_DHM_INVALID_FORMAT,
583 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
Daniel Kahn Gillmor2ed81732015-04-03 13:09:24 -0400584 goto exit;
585 }
Paul Bakker40ce79f2013-09-15 17:43:54 +0200586 }
587
588 ret = 0;
589
590exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200591#if defined(MBEDTLS_PEM_PARSE_C)
592 mbedtls_pem_free( &pem );
Paul Bakker40ce79f2013-09-15 17:43:54 +0200593#endif
594 if( ret != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200595 mbedtls_dhm_free( dhm );
Paul Bakker40ce79f2013-09-15 17:43:54 +0200596
597 return( ret );
598}
599
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200600#if defined(MBEDTLS_FS_IO)
Paul Bakker40ce79f2013-09-15 17:43:54 +0200601/*
602 * Load all data from a file into a given buffer.
Manuel Pégourié-Gonnard43b37cb2015-05-12 11:20:10 +0200603 *
604 * The file is expected to contain either PEM or DER encoded data.
605 * A terminating null byte is always appended. It is included in the announced
606 * length only if the data looks like it is PEM encoded.
Paul Bakker40ce79f2013-09-15 17:43:54 +0200607 */
608static int load_file( const char *path, unsigned char **buf, size_t *n )
609{
610 FILE *f;
611 long size;
612
613 if( ( f = fopen( path, "rb" ) ) == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200614 return( MBEDTLS_ERR_DHM_FILE_IO_ERROR );
Gilles Peskineda0913b2022-06-30 17:03:40 +0200615 /* The data loaded here is public, so don't bother disabling buffering. */
Paul Bakker40ce79f2013-09-15 17:43:54 +0200616
617 fseek( f, 0, SEEK_END );
618 if( ( size = ftell( f ) ) == -1 )
619 {
620 fclose( f );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200621 return( MBEDTLS_ERR_DHM_FILE_IO_ERROR );
Paul Bakker40ce79f2013-09-15 17:43:54 +0200622 }
623 fseek( f, 0, SEEK_SET );
624
625 *n = (size_t) size;
626
627 if( *n + 1 == 0 ||
Manuel Pégourié-Gonnard7551cb92015-05-26 16:04:06 +0200628 ( *buf = mbedtls_calloc( 1, *n + 1 ) ) == NULL )
Paul Bakker40ce79f2013-09-15 17:43:54 +0200629 {
630 fclose( f );
Manuel Pégourié-Gonnard6a8ca332015-05-28 09:33:39 +0200631 return( MBEDTLS_ERR_DHM_ALLOC_FAILED );
Paul Bakker40ce79f2013-09-15 17:43:54 +0200632 }
633
634 if( fread( *buf, 1, *n, f ) != *n )
635 {
636 fclose( f );
Andres Amaya Garciabdbca7b2017-06-23 16:23:21 +0100637
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500638 mbedtls_platform_zeroize( *buf, *n + 1 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200639 mbedtls_free( *buf );
Andres Amaya Garciabdbca7b2017-06-23 16:23:21 +0100640
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200641 return( MBEDTLS_ERR_DHM_FILE_IO_ERROR );
Paul Bakker40ce79f2013-09-15 17:43:54 +0200642 }
643
644 fclose( f );
645
646 (*buf)[*n] = '\0';
647
Manuel Pégourié-Gonnard43b37cb2015-05-12 11:20:10 +0200648 if( strstr( (const char *) *buf, "-----BEGIN " ) != NULL )
649 ++*n;
650
Paul Bakker40ce79f2013-09-15 17:43:54 +0200651 return( 0 );
652}
653
654/*
655 * Load and parse DHM parameters
656 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200657int mbedtls_dhm_parse_dhmfile( mbedtls_dhm_context *dhm, const char *path )
Paul Bakker40ce79f2013-09-15 17:43:54 +0200658{
Janos Follath24eed8d2019-11-22 13:21:35 +0000659 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker40ce79f2013-09-15 17:43:54 +0200660 size_t n;
661 unsigned char *buf;
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500662 DHM_VALIDATE_RET( dhm != NULL );
663 DHM_VALIDATE_RET( path != NULL );
Paul Bakker40ce79f2013-09-15 17:43:54 +0200664
Paul Bakker66d5d072014-06-17 16:39:18 +0200665 if( ( ret = load_file( path, &buf, &n ) ) != 0 )
Paul Bakker40ce79f2013-09-15 17:43:54 +0200666 return( ret );
667
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200668 ret = mbedtls_dhm_parse_dhm( dhm, buf, n );
Paul Bakker40ce79f2013-09-15 17:43:54 +0200669
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500670 mbedtls_platform_zeroize( buf, n );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200671 mbedtls_free( buf );
Paul Bakker40ce79f2013-09-15 17:43:54 +0200672
673 return( ret );
674}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200675#endif /* MBEDTLS_FS_IO */
676#endif /* MBEDTLS_ASN1_PARSE_C */
nirekh0149762fa2017-12-25 06:46:48 +0000677#endif /* MBEDTLS_DHM_ALT */
Paul Bakker40ce79f2013-09-15 17:43:54 +0200678
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200679#if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +0000680
Hanno Becker8b0f9e62019-05-31 17:28:59 +0100681#if defined(MBEDTLS_PEM_PARSE_C)
Manuel Pégourié-Gonnard53585ee2015-06-25 08:52:25 +0200682static const char mbedtls_test_dhm_params[] =
683"-----BEGIN DH PARAMETERS-----\r\n"
684"MIGHAoGBAJ419DBEOgmQTzo5qXl5fQcN9TN455wkOL7052HzxxRVMyhYmwQcgJvh\r\n"
685"1sa18fyfR9OiVEMYglOpkqVoGLN7qd5aQNNi5W7/C+VBdHTBJcGZJyyP5B3qcz32\r\n"
686"9mLJKudlVudV0Qxk5qUJaPZ/xupz0NyoVpviuiBOI1gNi8ovSXWzAgEC\r\n"
687"-----END DH PARAMETERS-----\r\n";
Hanno Becker8b0f9e62019-05-31 17:28:59 +0100688#else /* MBEDTLS_PEM_PARSE_C */
689static const char mbedtls_test_dhm_params[] = {
690 0x30, 0x81, 0x87, 0x02, 0x81, 0x81, 0x00, 0x9e, 0x35, 0xf4, 0x30, 0x44,
691 0x3a, 0x09, 0x90, 0x4f, 0x3a, 0x39, 0xa9, 0x79, 0x79, 0x7d, 0x07, 0x0d,
692 0xf5, 0x33, 0x78, 0xe7, 0x9c, 0x24, 0x38, 0xbe, 0xf4, 0xe7, 0x61, 0xf3,
693 0xc7, 0x14, 0x55, 0x33, 0x28, 0x58, 0x9b, 0x04, 0x1c, 0x80, 0x9b, 0xe1,
694 0xd6, 0xc6, 0xb5, 0xf1, 0xfc, 0x9f, 0x47, 0xd3, 0xa2, 0x54, 0x43, 0x18,
695 0x82, 0x53, 0xa9, 0x92, 0xa5, 0x68, 0x18, 0xb3, 0x7b, 0xa9, 0xde, 0x5a,
696 0x40, 0xd3, 0x62, 0xe5, 0x6e, 0xff, 0x0b, 0xe5, 0x41, 0x74, 0x74, 0xc1,
697 0x25, 0xc1, 0x99, 0x27, 0x2c, 0x8f, 0xe4, 0x1d, 0xea, 0x73, 0x3d, 0xf6,
698 0xf6, 0x62, 0xc9, 0x2a, 0xe7, 0x65, 0x56, 0xe7, 0x55, 0xd1, 0x0c, 0x64,
699 0xe6, 0xa5, 0x09, 0x68, 0xf6, 0x7f, 0xc6, 0xea, 0x73, 0xd0, 0xdc, 0xa8,
700 0x56, 0x9b, 0xe2, 0xba, 0x20, 0x4e, 0x23, 0x58, 0x0d, 0x8b, 0xca, 0x2f,
701 0x49, 0x75, 0xb3, 0x02, 0x01, 0x02 };
702#endif /* MBEDTLS_PEM_PARSE_C */
Manuel Pégourié-Gonnard53585ee2015-06-25 08:52:25 +0200703
704static const size_t mbedtls_test_dhm_params_len = sizeof( mbedtls_test_dhm_params );
Paul Bakker40ce79f2013-09-15 17:43:54 +0200705
Paul Bakker5121ce52009-01-03 21:22:43 +0000706/*
707 * Checkup routine
708 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200709int mbedtls_dhm_self_test( int verbose )
Paul Bakker5121ce52009-01-03 21:22:43 +0000710{
Janos Follath24eed8d2019-11-22 13:21:35 +0000711 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200712 mbedtls_dhm_context dhm;
Paul Bakker40ce79f2013-09-15 17:43:54 +0200713
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200714 mbedtls_dhm_init( &dhm );
Paul Bakker8f870b02014-06-20 13:32:38 +0200715
Paul Bakker40ce79f2013-09-15 17:43:54 +0200716 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200717 mbedtls_printf( " DHM parameter load: " );
Paul Bakker40ce79f2013-09-15 17:43:54 +0200718
Manuel Pégourié-Gonnard53585ee2015-06-25 08:52:25 +0200719 if( ( ret = mbedtls_dhm_parse_dhm( &dhm,
720 (const unsigned char *) mbedtls_test_dhm_params,
721 mbedtls_test_dhm_params_len ) ) != 0 )
Paul Bakker40ce79f2013-09-15 17:43:54 +0200722 {
723 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200724 mbedtls_printf( "failed\n" );
Paul Bakker40ce79f2013-09-15 17:43:54 +0200725
Manuel Pégourié-Gonnardb196fc22014-07-09 16:53:29 +0200726 ret = 1;
Paul Bakker8f870b02014-06-20 13:32:38 +0200727 goto exit;
Paul Bakker40ce79f2013-09-15 17:43:54 +0200728 }
729
730 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200731 mbedtls_printf( "passed\n\n" );
Paul Bakker40ce79f2013-09-15 17:43:54 +0200732
Paul Bakker8f870b02014-06-20 13:32:38 +0200733exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200734 mbedtls_dhm_free( &dhm );
Paul Bakker40ce79f2013-09-15 17:43:54 +0200735
Paul Bakker8f870b02014-06-20 13:32:38 +0200736 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000737}
738
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200739#endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +0000740
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200741#endif /* MBEDTLS_DHM_C */