blob: f2ad551ceb8aa4b3352bb0d3d62f7e3a61a36adc [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é-Gonnard2cf5a7c2015-04-08 12:49:31 +020046#if defined(MBEDTLS_PLATFORM_C)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000047#include "mbedtls/platform.h"
Paul Bakker40ce79f2013-09-15 17:43:54 +020048#else
49#include <stdlib.h>
Manuel Pégourié-Gonnard981732b2015-02-17 15:46:45 +000050#include <stdio.h>
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020051#define mbedtls_printf printf
Manuel Pégourié-Gonnard7551cb92015-05-26 16:04:06 +020052#define mbedtls_calloc calloc
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020053#define mbedtls_free free
Paul Bakker40ce79f2013-09-15 17:43:54 +020054#endif
55
Reuven Levin1f35ca92017-12-07 10:09:32 +000056#if !defined(MBEDTLS_DHM_ALT)
Paul Bakker34617722014-06-13 17:20:13 +020057
Andrzej Kurekc470b6b2019-01-31 08:20:20 -050058#define DHM_VALIDATE_RET( cond ) \
59 MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_DHM_BAD_INPUT_DATA )
60#define DHM_VALIDATE( cond ) \
61 MBEDTLS_INTERNAL_VALIDATE( cond )
62
Paul Bakker5121ce52009-01-03 21:22:43 +000063/*
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020064 * helper to validate the mbedtls_mpi size and import it
Paul Bakker5121ce52009-01-03 21:22:43 +000065 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020066static int dhm_read_bignum( mbedtls_mpi *X,
Paul Bakker5121ce52009-01-03 21:22:43 +000067 unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +000068 const unsigned char *end )
Paul Bakker5121ce52009-01-03 21:22:43 +000069{
70 int ret, n;
71
72 if( end - *p < 2 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020073 return( MBEDTLS_ERR_DHM_BAD_INPUT_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +000074
75 n = ( (*p)[0] << 8 ) | (*p)[1];
76 (*p) += 2;
77
78 if( (int)( end - *p ) < n )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020079 return( MBEDTLS_ERR_DHM_BAD_INPUT_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +000080
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020081 if( ( ret = mbedtls_mpi_read_binary( X, *p, n ) ) != 0 )
Chris Jones9f7a6932021-04-14 12:12:09 +010082 return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_DHM_READ_PARAMS_FAILED, ret ) );
Paul Bakker5121ce52009-01-03 21:22:43 +000083
84 (*p) += n;
85
86 return( 0 );
87}
88
89/*
Paul Bakkeraec37cb2012-04-26 18:59:59 +000090 * Verify sanity of parameter with regards to P
Paul Bakker345a6fe2011-02-28 21:20:02 +000091 *
Paul Bakkeraec37cb2012-04-26 18:59:59 +000092 * Parameter should be: 2 <= public_param <= P - 2
Paul Bakker345a6fe2011-02-28 21:20:02 +000093 *
Janos Follathaa325d72017-09-20 15:33:24 +010094 * This means that we need to return an error if
Janos Follath1ad1c6d2017-09-21 09:02:11 +010095 * public_param < 2 or public_param > P-2
Janos Follathaa325d72017-09-20 15:33:24 +010096 *
Paul Bakker345a6fe2011-02-28 21:20:02 +000097 * For more information on the attack, see:
98 * http://www.cl.cam.ac.uk/~rja14/Papers/psandqs.pdf
99 * http://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2005-2643
Paul Bakkerc47840e2011-02-20 16:37:30 +0000100 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200101static int dhm_check_range( const mbedtls_mpi *param, const mbedtls_mpi *P )
Paul Bakkerc47840e2011-02-20 16:37:30 +0000102{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200103 mbedtls_mpi L, U;
Janos Follathaa325d72017-09-20 15:33:24 +0100104 int ret = 0;
Paul Bakkerc47840e2011-02-20 16:37:30 +0000105
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200106 mbedtls_mpi_init( &L ); mbedtls_mpi_init( &U );
Paul Bakker3d8fb632014-04-17 12:42:41 +0200107
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200108 MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &L, 2 ) );
109 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &U, P, 2 ) );
Paul Bakkerc47840e2011-02-20 16:37:30 +0000110
Janos Follathaa325d72017-09-20 15:33:24 +0100111 if( mbedtls_mpi_cmp_mpi( param, &L ) < 0 ||
112 mbedtls_mpi_cmp_mpi( param, &U ) > 0 )
Paul Bakkerc47840e2011-02-20 16:37:30 +0000113 {
Janos Follathaa325d72017-09-20 15:33:24 +0100114 ret = MBEDTLS_ERR_DHM_BAD_INPUT_DATA;
Paul Bakkerc47840e2011-02-20 16:37:30 +0000115 }
116
Paul Bakker3d8fb632014-04-17 12:42:41 +0200117cleanup:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200118 mbedtls_mpi_free( &L ); mbedtls_mpi_free( &U );
Paul Bakker345a6fe2011-02-28 21:20:02 +0000119 return( ret );
Paul Bakkerc47840e2011-02-20 16:37:30 +0000120}
121
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200122void mbedtls_dhm_init( mbedtls_dhm_context *ctx )
Paul Bakker8f870b02014-06-20 13:32:38 +0200123{
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500124 DHM_VALIDATE( ctx != NULL );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200125 memset( ctx, 0, sizeof( mbedtls_dhm_context ) );
Paul Bakker8f870b02014-06-20 13:32:38 +0200126}
127
Paul Bakkerc47840e2011-02-20 16:37:30 +0000128/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000129 * Parse the ServerKeyExchange parameters
130 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200131int mbedtls_dhm_read_params( mbedtls_dhm_context *ctx,
Paul Bakker5121ce52009-01-03 21:22:43 +0000132 unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000133 const unsigned char *end )
Paul Bakker5121ce52009-01-03 21:22:43 +0000134{
Janos Follath24eed8d2019-11-22 13:21:35 +0000135 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500136 DHM_VALIDATE_RET( ctx != NULL );
137 DHM_VALIDATE_RET( p != NULL && *p != NULL );
138 DHM_VALIDATE_RET( end != NULL );
Paul Bakker5121ce52009-01-03 21:22:43 +0000139
Paul Bakker5121ce52009-01-03 21:22:43 +0000140 if( ( ret = dhm_read_bignum( &ctx->P, p, end ) ) != 0 ||
141 ( ret = dhm_read_bignum( &ctx->G, p, end ) ) != 0 ||
142 ( ret = dhm_read_bignum( &ctx->GY, p, end ) ) != 0 )
143 return( ret );
144
Paul Bakker345a6fe2011-02-28 21:20:02 +0000145 if( ( ret = dhm_check_range( &ctx->GY, &ctx->P ) ) != 0 )
146 return( ret );
147
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200148 ctx->len = mbedtls_mpi_size( &ctx->P );
Paul Bakker5121ce52009-01-03 21:22:43 +0000149
Paul Bakker5121ce52009-01-03 21:22:43 +0000150 return( 0 );
151}
152
Gilles Peskinecb660f22021-03-31 22:35:13 +0200153static int dhm_make_common( mbedtls_dhm_context *ctx, int x_size,
154 int (*f_rng)(void *, unsigned char *, size_t),
155 void *p_rng )
Paul Bakker5121ce52009-01-03 21:22:43 +0000156{
Paul Bakkeraec37cb2012-04-26 18:59:59 +0000157 int ret, count = 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000158
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200159 if( mbedtls_mpi_cmp_int( &ctx->P, 0 ) == 0 )
160 return( MBEDTLS_ERR_DHM_BAD_INPUT_DATA );
Paul Bakkerb5b20f12012-09-16 15:07:49 +0000161
Paul Bakker5121ce52009-01-03 21:22:43 +0000162 /*
Paul Bakkerff7fe672010-07-18 09:45:05 +0000163 * Generate X as large as possible ( < P )
Paul Bakker5121ce52009-01-03 21:22:43 +0000164 */
Paul Bakkeraec37cb2012-04-26 18:59:59 +0000165 do
166 {
Ron Eldor7269fee2017-01-12 14:50:50 +0200167 MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( &ctx->X, x_size, f_rng, p_rng ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000168
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200169 while( mbedtls_mpi_cmp_mpi( &ctx->X, &ctx->P ) >= 0 )
170 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &ctx->X, 1 ) );
Paul Bakkeraec37cb2012-04-26 18:59:59 +0000171
172 if( count++ > 10 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200173 return( MBEDTLS_ERR_DHM_MAKE_PARAMS_FAILED );
Paul Bakkeraec37cb2012-04-26 18:59:59 +0000174 }
175 while( dhm_check_range( &ctx->X, &ctx->P ) != 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000176
Paul Bakkerff7fe672010-07-18 09:45:05 +0000177 /*
178 * Calculate GX = G^X mod P
179 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200180 MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &ctx->GX, &ctx->G, &ctx->X,
Paul Bakker5121ce52009-01-03 21:22:43 +0000181 &ctx->P , &ctx->RP ) );
182
Paul Bakker345a6fe2011-02-28 21:20:02 +0000183 if( ( ret = dhm_check_range( &ctx->GX, &ctx->P ) ) != 0 )
Paul Bakkerc47840e2011-02-20 16:37:30 +0000184 return( ret );
185
Gilles Peskinecb660f22021-03-31 22:35:13 +0200186cleanup:
187 return( ret );
188}
189
190/*
191 * Setup and write the ServerKeyExchange parameters
192 */
193int mbedtls_dhm_make_params( mbedtls_dhm_context *ctx, int x_size,
194 unsigned char *output, size_t *olen,
195 int (*f_rng)(void *, unsigned char *, size_t),
196 void *p_rng )
197{
198 int ret;
199 size_t n1, n2, n3;
200 unsigned char *p;
201 DHM_VALIDATE_RET( ctx != NULL );
202 DHM_VALIDATE_RET( output != NULL );
203 DHM_VALIDATE_RET( olen != NULL );
204 DHM_VALIDATE_RET( f_rng != NULL );
205
206 ret = dhm_make_common( ctx, x_size, f_rng, p_rng );
207 if( ret != 0 )
208 goto cleanup;
209
Paul Bakker5121ce52009-01-03 21:22:43 +0000210 /*
211 * export P, G, GX
212 */
Hanno Beckerde6c1642017-10-02 15:03:15 +0100213#define DHM_MPI_EXPORT( X, n ) \
Hanno Beckere71ad122017-09-28 10:32:25 +0100214 do { \
Hanno Beckerde6c1642017-10-02 15:03:15 +0100215 MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( ( X ), \
216 p + 2, \
217 ( n ) ) ); \
218 *p++ = (unsigned char)( ( n ) >> 8 ); \
219 *p++ = (unsigned char)( ( n ) ); \
220 p += ( n ); \
Hanno Beckere71ad122017-09-28 10:32:25 +0100221 } while( 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000222
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200223 n1 = mbedtls_mpi_size( &ctx->P );
224 n2 = mbedtls_mpi_size( &ctx->G );
225 n3 = mbedtls_mpi_size( &ctx->GX );
Paul Bakker5121ce52009-01-03 21:22:43 +0000226
227 p = output;
228 DHM_MPI_EXPORT( &ctx->P , n1 );
229 DHM_MPI_EXPORT( &ctx->G , n2 );
230 DHM_MPI_EXPORT( &ctx->GX, n3 );
231
Hanno Beckere71ad122017-09-28 10:32:25 +0100232 *olen = p - output;
Paul Bakker5121ce52009-01-03 21:22:43 +0000233
234 ctx->len = n1;
235
236cleanup:
Gilles Peskinecb660f22021-03-31 22:35:13 +0200237 if( ret != 0 && ret > -128 )
238 ret = MBEDTLS_ERROR_ADD( MBEDTLS_ERR_DHM_MAKE_PARAMS_FAILED, ret );
239 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000240}
241
242/*
Hanno Becker8880e752017-10-04 13:15:08 +0100243 * Set prime modulus and generator
244 */
245int mbedtls_dhm_set_group( mbedtls_dhm_context *ctx,
246 const mbedtls_mpi *P,
247 const mbedtls_mpi *G )
248{
Janos Follath24eed8d2019-11-22 13:21:35 +0000249 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500250 DHM_VALIDATE_RET( ctx != NULL );
251 DHM_VALIDATE_RET( P != NULL );
252 DHM_VALIDATE_RET( G != NULL );
Hanno Becker8880e752017-10-04 13:15:08 +0100253
254 if( ( ret = mbedtls_mpi_copy( &ctx->P, P ) ) != 0 ||
255 ( ret = mbedtls_mpi_copy( &ctx->G, G ) ) != 0 )
256 {
Chris Jones9f7a6932021-04-14 12:12:09 +0100257 return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_DHM_SET_GROUP_FAILED, ret ) );
Hanno Becker8880e752017-10-04 13:15:08 +0100258 }
259
260 ctx->len = mbedtls_mpi_size( &ctx->P );
261 return( 0 );
262}
263
264/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000265 * Import the peer's public value G^Y
266 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200267int mbedtls_dhm_read_public( mbedtls_dhm_context *ctx,
Paul Bakker23986e52011-04-24 08:57:21 +0000268 const unsigned char *input, size_t ilen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000269{
Janos Follath24eed8d2019-11-22 13:21:35 +0000270 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500271 DHM_VALIDATE_RET( ctx != NULL );
272 DHM_VALIDATE_RET( input != NULL );
Paul Bakker5121ce52009-01-03 21:22:43 +0000273
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500274 if( ilen < 1 || ilen > ctx->len )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200275 return( MBEDTLS_ERR_DHM_BAD_INPUT_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +0000276
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200277 if( ( ret = mbedtls_mpi_read_binary( &ctx->GY, input, ilen ) ) != 0 )
Chris Jones9f7a6932021-04-14 12:12:09 +0100278 return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_DHM_READ_PUBLIC_FAILED, ret ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000279
280 return( 0 );
281}
282
283/*
284 * Create own private value X and export G^X
285 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200286int mbedtls_dhm_make_public( mbedtls_dhm_context *ctx, int x_size,
Paul Bakker23986e52011-04-24 08:57:21 +0000287 unsigned char *output, size_t olen,
Paul Bakkera3d195c2011-11-27 21:07:34 +0000288 int (*f_rng)(void *, unsigned char *, size_t),
289 void *p_rng )
Paul Bakker5121ce52009-01-03 21:22:43 +0000290{
Gilles Peskinecb660f22021-03-31 22:35:13 +0200291 int ret;
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500292 DHM_VALIDATE_RET( ctx != NULL );
293 DHM_VALIDATE_RET( output != NULL );
294 DHM_VALIDATE_RET( f_rng != NULL );
Paul Bakker5121ce52009-01-03 21:22:43 +0000295
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500296 if( olen < 1 || olen > ctx->len )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200297 return( MBEDTLS_ERR_DHM_BAD_INPUT_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +0000298
Gilles Peskinecb660f22021-03-31 22:35:13 +0200299 ret = dhm_make_common( ctx, x_size, f_rng, p_rng );
300 if( ret == MBEDTLS_ERR_DHM_MAKE_PARAMS_FAILED )
301 return( MBEDTLS_ERR_DHM_MAKE_PUBLIC_FAILED );
302 if( ret != 0 )
303 goto cleanup;
Paul Bakkerc47840e2011-02-20 16:37:30 +0000304
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200305 MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &ctx->GX, output, olen ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000306
307cleanup:
Gilles Peskinecb660f22021-03-31 22:35:13 +0200308 if( ret != 0 && ret > -128 )
309 ret = MBEDTLS_ERROR_ADD( MBEDTLS_ERR_DHM_MAKE_PUBLIC_FAILED, ret );
310 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000311}
312
313/*
Manuel Pégourié-Gonnard9f58c4b2020-06-25 12:34:58 +0200314 * Pick a random R in the range [2, M) for blinding purposes
315 */
316static int dhm_random_below( mbedtls_mpi *R, const mbedtls_mpi *M,
317 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
318{
319 int ret, count;
320
321 count = 0;
322 do
323 {
324 MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( R, mbedtls_mpi_size( M ), f_rng, p_rng ) );
325
326 while( mbedtls_mpi_cmp_mpi( R, M ) >= 0 )
327 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( R, 1 ) );
328
329 if( count++ > 10 )
330 return( MBEDTLS_ERR_MPI_NOT_ACCEPTABLE );
331 }
332 while( mbedtls_mpi_cmp_int( R, 1 ) <= 0 );
333
334cleanup:
335 return( ret );
336}
337
338
339/*
Manuel Pégourié-Gonnard143b5022013-09-04 16:29:59 +0200340 * Use the blinding method and optimisation suggested in section 10 of:
341 * KOCHER, Paul C. Timing attacks on implementations of Diffie-Hellman, RSA,
Manuel Pégourié-Gonnard998930a2015-04-03 13:48:06 +0200342 * DSS, and other systems. In : Advances in Cryptology-CRYPTO'96. Springer
Manuel Pégourié-Gonnard143b5022013-09-04 16:29:59 +0200343 * Berlin Heidelberg, 1996. p. 104-113.
344 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200345static int dhm_update_blinding( mbedtls_dhm_context *ctx,
Manuel Pégourié-Gonnard143b5022013-09-04 16:29:59 +0200346 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
347{
Manuel Pégourié-Gonnard9f58c4b2020-06-25 12:34:58 +0200348 int ret;
Manuel Pégourié-Gonnardaf721672020-06-25 12:47:22 +0200349 mbedtls_mpi R;
350
351 mbedtls_mpi_init( &R );
Manuel Pégourié-Gonnard143b5022013-09-04 16:29:59 +0200352
353 /*
Manuel Pégourié-Gonnard15d5de12013-09-17 11:34:11 +0200354 * Don't use any blinding the first time a particular X is used,
355 * but remember it to use blinding next time.
Manuel Pégourié-Gonnard143b5022013-09-04 16:29:59 +0200356 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200357 if( mbedtls_mpi_cmp_mpi( &ctx->X, &ctx->pX ) != 0 )
Manuel Pégourié-Gonnarded8a02b2013-09-04 16:39:03 +0200358 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200359 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &ctx->pX, &ctx->X ) );
360 MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &ctx->Vi, 1 ) );
361 MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &ctx->Vf, 1 ) );
Manuel Pégourié-Gonnarded8a02b2013-09-04 16:39:03 +0200362
Manuel Pégourié-Gonnard143b5022013-09-04 16:29:59 +0200363 return( 0 );
364 }
365
366 /*
Manuel Pégourié-Gonnard15d5de12013-09-17 11:34:11 +0200367 * Ok, we need blinding. Can we re-use existing values?
368 * If yes, just update them by squaring them.
Manuel Pégourié-Gonnard143b5022013-09-04 16:29:59 +0200369 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200370 if( mbedtls_mpi_cmp_int( &ctx->Vi, 1 ) != 0 )
Manuel Pégourié-Gonnard15d5de12013-09-17 11:34:11 +0200371 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200372 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &ctx->Vi, &ctx->Vi, &ctx->Vi ) );
373 MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &ctx->Vi, &ctx->Vi, &ctx->P ) );
Manuel Pégourié-Gonnard15d5de12013-09-17 11:34:11 +0200374
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200375 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &ctx->Vf, &ctx->Vf, &ctx->Vf ) );
376 MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &ctx->Vf, &ctx->Vf, &ctx->P ) );
Manuel Pégourié-Gonnard15d5de12013-09-17 11:34:11 +0200377
378 return( 0 );
379 }
380
381 /*
382 * We need to generate blinding values from scratch
383 */
384
385 /* Vi = random( 2, P-1 ) */
Manuel Pégourié-Gonnard9f58c4b2020-06-25 12:34:58 +0200386 MBEDTLS_MPI_CHK( dhm_random_below( &ctx->Vi, &ctx->P, f_rng, p_rng ) );
Manuel Pégourié-Gonnard15d5de12013-09-17 11:34:11 +0200387
Manuel Pégourié-Gonnardaf721672020-06-25 12:47:22 +0200388 /* Vf = Vi^-X mod P
389 * First compute Vi^-1 = R * (R Vi)^-1, (avoiding leaks from inv_mod),
390 * then elevate to the Xth power. */
391 MBEDTLS_MPI_CHK( dhm_random_below( &R, &ctx->P, f_rng, p_rng ) );
392 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &ctx->Vf, &ctx->Vi, &R ) );
393 MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &ctx->Vf, &ctx->Vf, &ctx->P ) );
394 MBEDTLS_MPI_CHK( mbedtls_mpi_inv_mod( &ctx->Vf, &ctx->Vf, &ctx->P ) );
395 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &ctx->Vf, &ctx->Vf, &R ) );
396 MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &ctx->Vf, &ctx->Vf, &ctx->P ) );
Manuel Pégourié-Gonnard15d5de12013-09-17 11:34:11 +0200397
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200398 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 +0200399
Manuel Pégourié-Gonnard143b5022013-09-04 16:29:59 +0200400cleanup:
Manuel Pégourié-Gonnardaf721672020-06-25 12:47:22 +0200401 mbedtls_mpi_free( &R );
402
Manuel Pégourié-Gonnard143b5022013-09-04 16:29:59 +0200403 return( ret );
404}
405
406/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000407 * Derive and export the shared secret (G^Y)^X mod P
408 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200409int mbedtls_dhm_calc_secret( mbedtls_dhm_context *ctx,
Manuel Pégourié-Gonnard33352052015-06-02 16:17:08 +0100410 unsigned char *output, size_t output_size, size_t *olen,
Manuel Pégourié-Gonnard2d627642013-09-04 14:22:07 +0200411 int (*f_rng)(void *, unsigned char *, size_t),
412 void *p_rng )
Paul Bakker5121ce52009-01-03 21:22:43 +0000413{
Janos Follath24eed8d2019-11-22 13:21:35 +0000414 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200415 mbedtls_mpi GYb;
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500416 DHM_VALIDATE_RET( ctx != NULL );
417 DHM_VALIDATE_RET( output != NULL );
418 DHM_VALIDATE_RET( olen != NULL );
Manuel Pégourié-Gonnard2d627642013-09-04 14:22:07 +0200419
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500420 if( output_size < ctx->len )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200421 return( MBEDTLS_ERR_DHM_BAD_INPUT_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +0000422
Paul Bakker345a6fe2011-02-28 21:20:02 +0000423 if( ( ret = dhm_check_range( &ctx->GY, &ctx->P ) ) != 0 )
Paul Bakkerc47840e2011-02-20 16:37:30 +0000424 return( ret );
425
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200426 mbedtls_mpi_init( &GYb );
Manuel Pégourié-Gonnard143b5022013-09-04 16:29:59 +0200427
428 /* Blind peer's value */
Manuel Pégourié-Gonnarded8a02b2013-09-04 16:39:03 +0200429 if( f_rng != NULL )
Manuel Pégourié-Gonnard143b5022013-09-04 16:29:59 +0200430 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200431 MBEDTLS_MPI_CHK( dhm_update_blinding( ctx, f_rng, p_rng ) );
432 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &GYb, &ctx->GY, &ctx->Vi ) );
433 MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &GYb, &GYb, &ctx->P ) );
Manuel Pégourié-Gonnard143b5022013-09-04 16:29:59 +0200434 }
435 else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200436 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &GYb, &ctx->GY ) );
Manuel Pégourié-Gonnard143b5022013-09-04 16:29:59 +0200437
438 /* Do modular exponentiation */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200439 MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &ctx->K, &GYb, &ctx->X,
Manuel Pégourié-Gonnard143b5022013-09-04 16:29:59 +0200440 &ctx->P, &ctx->RP ) );
441
442 /* Unblind secret value */
Manuel Pégourié-Gonnarded8a02b2013-09-04 16:39:03 +0200443 if( f_rng != NULL )
Manuel Pégourié-Gonnard143b5022013-09-04 16:29:59 +0200444 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200445 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &ctx->K, &ctx->K, &ctx->Vf ) );
446 MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &ctx->K, &ctx->K, &ctx->P ) );
Manuel Pégourié-Gonnard143b5022013-09-04 16:29:59 +0200447 }
448
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200449 *olen = mbedtls_mpi_size( &ctx->K );
Paul Bakker5121ce52009-01-03 21:22:43 +0000450
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200451 MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &ctx->K, output, *olen ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000452
453cleanup:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200454 mbedtls_mpi_free( &GYb );
Paul Bakker5121ce52009-01-03 21:22:43 +0000455
456 if( ret != 0 )
Chris Jones9f7a6932021-04-14 12:12:09 +0100457 return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_DHM_CALC_SECRET_FAILED, ret ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000458
459 return( 0 );
460}
461
462/*
463 * Free the components of a DHM key
464 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200465void mbedtls_dhm_free( mbedtls_dhm_context *ctx )
Paul Bakker5121ce52009-01-03 21:22:43 +0000466{
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500467 if( ctx == NULL )
468 return;
469
470 mbedtls_mpi_free( &ctx->pX );
471 mbedtls_mpi_free( &ctx->Vf );
472 mbedtls_mpi_free( &ctx->Vi );
473 mbedtls_mpi_free( &ctx->RP );
474 mbedtls_mpi_free( &ctx->K );
475 mbedtls_mpi_free( &ctx->GY );
476 mbedtls_mpi_free( &ctx->GX );
477 mbedtls_mpi_free( &ctx->X );
478 mbedtls_mpi_free( &ctx->G );
479 mbedtls_mpi_free( &ctx->P );
Manuel Pégourié-Gonnardb72b4ed2013-09-13 13:55:26 +0200480
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500481 mbedtls_platform_zeroize( ctx, sizeof( mbedtls_dhm_context ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000482}
483
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200484#if defined(MBEDTLS_ASN1_PARSE_C)
Paul Bakker40ce79f2013-09-15 17:43:54 +0200485/*
486 * Parse DHM parameters
487 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200488int mbedtls_dhm_parse_dhm( mbedtls_dhm_context *dhm, const unsigned char *dhmin,
Paul Bakkerb9e4e2c2014-05-01 14:18:25 +0200489 size_t dhminlen )
Paul Bakker40ce79f2013-09-15 17:43:54 +0200490{
Janos Follath24eed8d2019-11-22 13:21:35 +0000491 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker40ce79f2013-09-15 17:43:54 +0200492 size_t len;
493 unsigned char *p, *end;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200494#if defined(MBEDTLS_PEM_PARSE_C)
495 mbedtls_pem_context pem;
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500496#endif /* MBEDTLS_PEM_PARSE_C */
Paul Bakker40ce79f2013-09-15 17:43:54 +0200497
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500498 DHM_VALIDATE_RET( dhm != NULL );
499 DHM_VALIDATE_RET( dhmin != NULL );
500
501#if defined(MBEDTLS_PEM_PARSE_C)
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200502 mbedtls_pem_init( &pem );
Paul Bakker40ce79f2013-09-15 17:43:54 +0200503
Manuel Pégourié-Gonnard43b37cb2015-05-12 11:20:10 +0200504 /* Avoid calling mbedtls_pem_read_buffer() on non-null-terminated string */
Manuel Pégourié-Gonnard0ece0f92015-05-12 12:43:54 +0200505 if( dhminlen == 0 || dhmin[dhminlen - 1] != '\0' )
Manuel Pégourié-Gonnard43b37cb2015-05-12 11:20:10 +0200506 ret = MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT;
507 else
508 ret = mbedtls_pem_read_buffer( &pem,
509 "-----BEGIN DH PARAMETERS-----",
510 "-----END DH PARAMETERS-----",
511 dhmin, NULL, 0, &dhminlen );
Paul Bakker40ce79f2013-09-15 17:43:54 +0200512
513 if( ret == 0 )
514 {
515 /*
516 * Was PEM encoded
517 */
518 dhminlen = pem.buflen;
519 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200520 else if( ret != MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
Paul Bakker40ce79f2013-09-15 17:43:54 +0200521 goto exit;
522
523 p = ( ret == 0 ) ? pem.buf : (unsigned char *) dhmin;
524#else
525 p = (unsigned char *) dhmin;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200526#endif /* MBEDTLS_PEM_PARSE_C */
Paul Bakker40ce79f2013-09-15 17:43:54 +0200527 end = p + dhminlen;
528
529 /*
530 * DHParams ::= SEQUENCE {
Daniel Kahn Gillmor2ed81732015-04-03 13:09:24 -0400531 * prime INTEGER, -- P
532 * generator INTEGER, -- g
533 * privateValueLength INTEGER OPTIONAL
Paul Bakker40ce79f2013-09-15 17:43:54 +0200534 * }
535 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200536 if( ( ret = mbedtls_asn1_get_tag( &p, end, &len,
537 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
Paul Bakker40ce79f2013-09-15 17:43:54 +0200538 {
Chris Jones9f7a6932021-04-14 12:12:09 +0100539 ret = MBEDTLS_ERROR_ADD( MBEDTLS_ERR_DHM_INVALID_FORMAT, ret );
Paul Bakker40ce79f2013-09-15 17:43:54 +0200540 goto exit;
541 }
542
543 end = p + len;
544
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200545 if( ( ret = mbedtls_asn1_get_mpi( &p, end, &dhm->P ) ) != 0 ||
546 ( ret = mbedtls_asn1_get_mpi( &p, end, &dhm->G ) ) != 0 )
Paul Bakker40ce79f2013-09-15 17:43:54 +0200547 {
Chris Jones9f7a6932021-04-14 12:12:09 +0100548 ret = MBEDTLS_ERROR_ADD( MBEDTLS_ERR_DHM_INVALID_FORMAT, ret );
Paul Bakker40ce79f2013-09-15 17:43:54 +0200549 goto exit;
550 }
551
552 if( p != end )
553 {
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;
557 mbedtls_mpi_init( &rec );
558 ret = mbedtls_asn1_get_mpi( &p, end, &rec );
559 mbedtls_mpi_free( &rec );
Daniel Kahn Gillmor2ed81732015-04-03 13:09:24 -0400560 if ( ret != 0 )
561 {
Chris Jones9f7a6932021-04-14 12:12:09 +0100562 ret = MBEDTLS_ERROR_ADD( MBEDTLS_ERR_DHM_INVALID_FORMAT, ret );
Daniel Kahn Gillmor2ed81732015-04-03 13:09:24 -0400563 goto exit;
564 }
565 if ( p != end )
566 {
Chris Jones9f7a6932021-04-14 12:12:09 +0100567 ret = MBEDTLS_ERROR_ADD( MBEDTLS_ERR_DHM_INVALID_FORMAT,
568 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
Daniel Kahn Gillmor2ed81732015-04-03 13:09:24 -0400569 goto exit;
570 }
Paul Bakker40ce79f2013-09-15 17:43:54 +0200571 }
572
573 ret = 0;
574
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200575 dhm->len = mbedtls_mpi_size( &dhm->P );
Manuel Pégourié-Gonnard3fec2202014-03-29 16:42:38 +0100576
Paul Bakker40ce79f2013-09-15 17:43:54 +0200577exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200578#if defined(MBEDTLS_PEM_PARSE_C)
579 mbedtls_pem_free( &pem );
Paul Bakker40ce79f2013-09-15 17:43:54 +0200580#endif
581 if( ret != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200582 mbedtls_dhm_free( dhm );
Paul Bakker40ce79f2013-09-15 17:43:54 +0200583
584 return( ret );
585}
586
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200587#if defined(MBEDTLS_FS_IO)
Paul Bakker40ce79f2013-09-15 17:43:54 +0200588/*
589 * Load all data from a file into a given buffer.
Manuel Pégourié-Gonnard43b37cb2015-05-12 11:20:10 +0200590 *
591 * The file is expected to contain either PEM or DER encoded data.
592 * A terminating null byte is always appended. It is included in the announced
593 * length only if the data looks like it is PEM encoded.
Paul Bakker40ce79f2013-09-15 17:43:54 +0200594 */
595static int load_file( const char *path, unsigned char **buf, size_t *n )
596{
597 FILE *f;
598 long size;
599
600 if( ( f = fopen( path, "rb" ) ) == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200601 return( MBEDTLS_ERR_DHM_FILE_IO_ERROR );
Paul Bakker40ce79f2013-09-15 17:43:54 +0200602
603 fseek( f, 0, SEEK_END );
604 if( ( size = ftell( f ) ) == -1 )
605 {
606 fclose( f );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200607 return( MBEDTLS_ERR_DHM_FILE_IO_ERROR );
Paul Bakker40ce79f2013-09-15 17:43:54 +0200608 }
609 fseek( f, 0, SEEK_SET );
610
611 *n = (size_t) size;
612
613 if( *n + 1 == 0 ||
Manuel Pégourié-Gonnard7551cb92015-05-26 16:04:06 +0200614 ( *buf = mbedtls_calloc( 1, *n + 1 ) ) == NULL )
Paul Bakker40ce79f2013-09-15 17:43:54 +0200615 {
616 fclose( f );
Manuel Pégourié-Gonnard6a8ca332015-05-28 09:33:39 +0200617 return( MBEDTLS_ERR_DHM_ALLOC_FAILED );
Paul Bakker40ce79f2013-09-15 17:43:54 +0200618 }
619
620 if( fread( *buf, 1, *n, f ) != *n )
621 {
622 fclose( f );
Andres Amaya Garciabdbca7b2017-06-23 16:23:21 +0100623
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500624 mbedtls_platform_zeroize( *buf, *n + 1 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200625 mbedtls_free( *buf );
Andres Amaya Garciabdbca7b2017-06-23 16:23:21 +0100626
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200627 return( MBEDTLS_ERR_DHM_FILE_IO_ERROR );
Paul Bakker40ce79f2013-09-15 17:43:54 +0200628 }
629
630 fclose( f );
631
632 (*buf)[*n] = '\0';
633
Manuel Pégourié-Gonnard43b37cb2015-05-12 11:20:10 +0200634 if( strstr( (const char *) *buf, "-----BEGIN " ) != NULL )
635 ++*n;
636
Paul Bakker40ce79f2013-09-15 17:43:54 +0200637 return( 0 );
638}
639
640/*
641 * Load and parse DHM parameters
642 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200643int mbedtls_dhm_parse_dhmfile( mbedtls_dhm_context *dhm, const char *path )
Paul Bakker40ce79f2013-09-15 17:43:54 +0200644{
Janos Follath24eed8d2019-11-22 13:21:35 +0000645 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker40ce79f2013-09-15 17:43:54 +0200646 size_t n;
647 unsigned char *buf;
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500648 DHM_VALIDATE_RET( dhm != NULL );
649 DHM_VALIDATE_RET( path != NULL );
Paul Bakker40ce79f2013-09-15 17:43:54 +0200650
Paul Bakker66d5d072014-06-17 16:39:18 +0200651 if( ( ret = load_file( path, &buf, &n ) ) != 0 )
Paul Bakker40ce79f2013-09-15 17:43:54 +0200652 return( ret );
653
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200654 ret = mbedtls_dhm_parse_dhm( dhm, buf, n );
Paul Bakker40ce79f2013-09-15 17:43:54 +0200655
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500656 mbedtls_platform_zeroize( buf, n );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200657 mbedtls_free( buf );
Paul Bakker40ce79f2013-09-15 17:43:54 +0200658
659 return( ret );
660}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200661#endif /* MBEDTLS_FS_IO */
662#endif /* MBEDTLS_ASN1_PARSE_C */
nirekh0149762fa2017-12-25 06:46:48 +0000663#endif /* MBEDTLS_DHM_ALT */
Paul Bakker40ce79f2013-09-15 17:43:54 +0200664
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200665#if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +0000666
Hanno Becker8b0f9e62019-05-31 17:28:59 +0100667#if defined(MBEDTLS_PEM_PARSE_C)
Manuel Pégourié-Gonnard53585ee2015-06-25 08:52:25 +0200668static const char mbedtls_test_dhm_params[] =
669"-----BEGIN DH PARAMETERS-----\r\n"
670"MIGHAoGBAJ419DBEOgmQTzo5qXl5fQcN9TN455wkOL7052HzxxRVMyhYmwQcgJvh\r\n"
671"1sa18fyfR9OiVEMYglOpkqVoGLN7qd5aQNNi5W7/C+VBdHTBJcGZJyyP5B3qcz32\r\n"
672"9mLJKudlVudV0Qxk5qUJaPZ/xupz0NyoVpviuiBOI1gNi8ovSXWzAgEC\r\n"
673"-----END DH PARAMETERS-----\r\n";
Hanno Becker8b0f9e62019-05-31 17:28:59 +0100674#else /* MBEDTLS_PEM_PARSE_C */
675static const char mbedtls_test_dhm_params[] = {
676 0x30, 0x81, 0x87, 0x02, 0x81, 0x81, 0x00, 0x9e, 0x35, 0xf4, 0x30, 0x44,
677 0x3a, 0x09, 0x90, 0x4f, 0x3a, 0x39, 0xa9, 0x79, 0x79, 0x7d, 0x07, 0x0d,
678 0xf5, 0x33, 0x78, 0xe7, 0x9c, 0x24, 0x38, 0xbe, 0xf4, 0xe7, 0x61, 0xf3,
679 0xc7, 0x14, 0x55, 0x33, 0x28, 0x58, 0x9b, 0x04, 0x1c, 0x80, 0x9b, 0xe1,
680 0xd6, 0xc6, 0xb5, 0xf1, 0xfc, 0x9f, 0x47, 0xd3, 0xa2, 0x54, 0x43, 0x18,
681 0x82, 0x53, 0xa9, 0x92, 0xa5, 0x68, 0x18, 0xb3, 0x7b, 0xa9, 0xde, 0x5a,
682 0x40, 0xd3, 0x62, 0xe5, 0x6e, 0xff, 0x0b, 0xe5, 0x41, 0x74, 0x74, 0xc1,
683 0x25, 0xc1, 0x99, 0x27, 0x2c, 0x8f, 0xe4, 0x1d, 0xea, 0x73, 0x3d, 0xf6,
684 0xf6, 0x62, 0xc9, 0x2a, 0xe7, 0x65, 0x56, 0xe7, 0x55, 0xd1, 0x0c, 0x64,
685 0xe6, 0xa5, 0x09, 0x68, 0xf6, 0x7f, 0xc6, 0xea, 0x73, 0xd0, 0xdc, 0xa8,
686 0x56, 0x9b, 0xe2, 0xba, 0x20, 0x4e, 0x23, 0x58, 0x0d, 0x8b, 0xca, 0x2f,
687 0x49, 0x75, 0xb3, 0x02, 0x01, 0x02 };
688#endif /* MBEDTLS_PEM_PARSE_C */
Manuel Pégourié-Gonnard53585ee2015-06-25 08:52:25 +0200689
690static const size_t mbedtls_test_dhm_params_len = sizeof( mbedtls_test_dhm_params );
Paul Bakker40ce79f2013-09-15 17:43:54 +0200691
Paul Bakker5121ce52009-01-03 21:22:43 +0000692/*
693 * Checkup routine
694 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200695int mbedtls_dhm_self_test( int verbose )
Paul Bakker5121ce52009-01-03 21:22:43 +0000696{
Janos Follath24eed8d2019-11-22 13:21:35 +0000697 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200698 mbedtls_dhm_context dhm;
Paul Bakker40ce79f2013-09-15 17:43:54 +0200699
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200700 mbedtls_dhm_init( &dhm );
Paul Bakker8f870b02014-06-20 13:32:38 +0200701
Paul Bakker40ce79f2013-09-15 17:43:54 +0200702 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200703 mbedtls_printf( " DHM parameter load: " );
Paul Bakker40ce79f2013-09-15 17:43:54 +0200704
Manuel Pégourié-Gonnard53585ee2015-06-25 08:52:25 +0200705 if( ( ret = mbedtls_dhm_parse_dhm( &dhm,
706 (const unsigned char *) mbedtls_test_dhm_params,
707 mbedtls_test_dhm_params_len ) ) != 0 )
Paul Bakker40ce79f2013-09-15 17:43:54 +0200708 {
709 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200710 mbedtls_printf( "failed\n" );
Paul Bakker40ce79f2013-09-15 17:43:54 +0200711
Manuel Pégourié-Gonnardb196fc22014-07-09 16:53:29 +0200712 ret = 1;
Paul Bakker8f870b02014-06-20 13:32:38 +0200713 goto exit;
Paul Bakker40ce79f2013-09-15 17:43:54 +0200714 }
715
716 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200717 mbedtls_printf( "passed\n\n" );
Paul Bakker40ce79f2013-09-15 17:43:54 +0200718
Paul Bakker8f870b02014-06-20 13:32:38 +0200719exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200720 mbedtls_dhm_free( &dhm );
Paul Bakker40ce79f2013-09-15 17:43:54 +0200721
Paul Bakker8f870b02014-06-20 13:32:38 +0200722 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000723}
724
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200725#endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +0000726
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200727#endif /* MBEDTLS_DHM_C */