blob: befa99850451392c5a8a83feba6a4cd7fe7b8ab5 [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{
Gilles Peskine58df4c92021-03-31 22:56:43 +0200103 mbedtls_mpi U;
Janos Follathaa325d72017-09-20 15:33:24 +0100104 int ret = 0;
Paul Bakkerc47840e2011-02-20 16:37:30 +0000105
Gilles Peskine58df4c92021-03-31 22:56:43 +0200106 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_sub_int( &U, P, 2 ) );
Paul Bakkerc47840e2011-02-20 16:37:30 +0000109
Gilles Peskine58df4c92021-03-31 22:56:43 +0200110 if( mbedtls_mpi_cmp_int( param, 2 ) < 0 ||
Janos Follathaa325d72017-09-20 15:33:24 +0100111 mbedtls_mpi_cmp_mpi( param, &U ) > 0 )
Paul Bakkerc47840e2011-02-20 16:37:30 +0000112 {
Janos Follathaa325d72017-09-20 15:33:24 +0100113 ret = MBEDTLS_ERR_DHM_BAD_INPUT_DATA;
Paul Bakkerc47840e2011-02-20 16:37:30 +0000114 }
115
Paul Bakker3d8fb632014-04-17 12:42:41 +0200116cleanup:
Gilles Peskine58df4c92021-03-31 22:56:43 +0200117 mbedtls_mpi_free( &U );
Paul Bakker345a6fe2011-02-28 21:20:02 +0000118 return( ret );
Paul Bakkerc47840e2011-02-20 16:37:30 +0000119}
120
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200121void mbedtls_dhm_init( mbedtls_dhm_context *ctx )
Paul Bakker8f870b02014-06-20 13:32:38 +0200122{
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500123 DHM_VALIDATE( ctx != NULL );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200124 memset( ctx, 0, sizeof( mbedtls_dhm_context ) );
Paul Bakker8f870b02014-06-20 13:32:38 +0200125}
126
Paul Bakkerc47840e2011-02-20 16:37:30 +0000127/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000128 * Parse the ServerKeyExchange parameters
129 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200130int mbedtls_dhm_read_params( mbedtls_dhm_context *ctx,
Paul Bakker5121ce52009-01-03 21:22:43 +0000131 unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000132 const unsigned char *end )
Paul Bakker5121ce52009-01-03 21:22:43 +0000133{
Janos Follath24eed8d2019-11-22 13:21:35 +0000134 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500135 DHM_VALIDATE_RET( ctx != NULL );
136 DHM_VALIDATE_RET( p != NULL && *p != NULL );
137 DHM_VALIDATE_RET( end != NULL );
Paul Bakker5121ce52009-01-03 21:22:43 +0000138
Paul Bakker5121ce52009-01-03 21:22:43 +0000139 if( ( ret = dhm_read_bignum( &ctx->P, p, end ) ) != 0 ||
140 ( ret = dhm_read_bignum( &ctx->G, p, end ) ) != 0 ||
141 ( ret = dhm_read_bignum( &ctx->GY, p, end ) ) != 0 )
142 return( ret );
143
Paul Bakker345a6fe2011-02-28 21:20:02 +0000144 if( ( ret = dhm_check_range( &ctx->GY, &ctx->P ) ) != 0 )
145 return( ret );
146
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200147 ctx->len = mbedtls_mpi_size( &ctx->P );
Paul Bakker5121ce52009-01-03 21:22:43 +0000148
Paul Bakker5121ce52009-01-03 21:22:43 +0000149 return( 0 );
150}
151
Gilles Peskine87fdb1f2021-03-31 22:48:14 +0200152/*
153 * Pick a random R in the range [2, M) for blinding or key generation.
154 */
155static int dhm_random_below( mbedtls_mpi *R, const mbedtls_mpi *M,
156 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
157{
158 int ret, count;
159
160 count = 0;
161 do
162 {
163 MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( R, mbedtls_mpi_size( M ), f_rng, p_rng ) );
164
165 while( mbedtls_mpi_cmp_mpi( R, M ) >= 0 )
166 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( R, 1 ) );
167
168 if( count++ > 10 )
169 return( MBEDTLS_ERR_MPI_NOT_ACCEPTABLE );
170 }
171 while( dhm_check_range( R, M ) != 0 );
172
173cleanup:
174 return( ret );
175}
176
Gilles Peskine0853bb22021-03-31 22:35:13 +0200177static int dhm_make_common( mbedtls_dhm_context *ctx, int x_size,
178 int (*f_rng)(void *, unsigned char *, size_t),
179 void *p_rng )
Paul Bakker5121ce52009-01-03 21:22:43 +0000180{
Gilles Peskine87fdb1f2021-03-31 22:48:14 +0200181 int ret = 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000182
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200183 if( mbedtls_mpi_cmp_int( &ctx->P, 0 ) == 0 )
184 return( MBEDTLS_ERR_DHM_BAD_INPUT_DATA );
Gilles Peskine87fdb1f2021-03-31 22:48:14 +0200185 if( x_size < 0 )
186 return( MBEDTLS_ERR_DHM_BAD_INPUT_DATA );
Paul Bakkerb5b20f12012-09-16 15:07:49 +0000187
Gilles Peskine87fdb1f2021-03-31 22:48:14 +0200188 if( (unsigned) x_size < mbedtls_mpi_size( &ctx->P ) )
Paul Bakkeraec37cb2012-04-26 18:59:59 +0000189 {
Ron Eldor7269fee2017-01-12 14:50:50 +0200190 MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( &ctx->X, x_size, f_rng, p_rng ) );
Paul Bakkeraec37cb2012-04-26 18:59:59 +0000191 }
Gilles Peskine87fdb1f2021-03-31 22:48:14 +0200192 else
193 {
194 /* Generate X as large as possible ( <= P - 2 ) */
195 ret = dhm_random_below( &ctx->X, &ctx->P, f_rng, p_rng );
196 if( ret == MBEDTLS_ERR_MPI_NOT_ACCEPTABLE )
197 return( MBEDTLS_ERR_DHM_MAKE_PARAMS_FAILED );
198 if( ret != 0 )
199 return( ret );
200 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000201
Paul Bakkerff7fe672010-07-18 09:45:05 +0000202 /*
203 * Calculate GX = G^X mod P
204 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200205 MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &ctx->GX, &ctx->G, &ctx->X,
Paul Bakker5121ce52009-01-03 21:22:43 +0000206 &ctx->P , &ctx->RP ) );
207
Paul Bakker345a6fe2011-02-28 21:20:02 +0000208 if( ( ret = dhm_check_range( &ctx->GX, &ctx->P ) ) != 0 )
Paul Bakkerc47840e2011-02-20 16:37:30 +0000209 return( ret );
210
Gilles Peskine0853bb22021-03-31 22:35:13 +0200211cleanup:
212 return( ret );
213}
214
215/*
216 * Setup and write the ServerKeyExchange parameters
217 */
218int mbedtls_dhm_make_params( mbedtls_dhm_context *ctx, int x_size,
219 unsigned char *output, size_t *olen,
220 int (*f_rng)(void *, unsigned char *, size_t),
221 void *p_rng )
222{
223 int ret;
224 size_t n1, n2, n3;
225 unsigned char *p;
226 DHM_VALIDATE_RET( ctx != NULL );
227 DHM_VALIDATE_RET( output != NULL );
228 DHM_VALIDATE_RET( olen != NULL );
229 DHM_VALIDATE_RET( f_rng != NULL );
230
231 ret = dhm_make_common( ctx, x_size, f_rng, p_rng );
232 if( ret != 0 )
233 goto cleanup;
234
Paul Bakker5121ce52009-01-03 21:22:43 +0000235 /*
236 * export P, G, GX
237 */
Hanno Beckerde6c1642017-10-02 15:03:15 +0100238#define DHM_MPI_EXPORT( X, n ) \
Hanno Beckere71ad122017-09-28 10:32:25 +0100239 do { \
Hanno Beckerde6c1642017-10-02 15:03:15 +0100240 MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( ( X ), \
241 p + 2, \
242 ( n ) ) ); \
243 *p++ = (unsigned char)( ( n ) >> 8 ); \
244 *p++ = (unsigned char)( ( n ) ); \
245 p += ( n ); \
Hanno Beckere71ad122017-09-28 10:32:25 +0100246 } while( 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000247
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200248 n1 = mbedtls_mpi_size( &ctx->P );
249 n2 = mbedtls_mpi_size( &ctx->G );
250 n3 = mbedtls_mpi_size( &ctx->GX );
Paul Bakker5121ce52009-01-03 21:22:43 +0000251
252 p = output;
253 DHM_MPI_EXPORT( &ctx->P , n1 );
254 DHM_MPI_EXPORT( &ctx->G , n2 );
255 DHM_MPI_EXPORT( &ctx->GX, n3 );
256
Hanno Beckere71ad122017-09-28 10:32:25 +0100257 *olen = p - output;
Paul Bakker5121ce52009-01-03 21:22:43 +0000258
259 ctx->len = n1;
260
261cleanup:
Gilles Peskine0853bb22021-03-31 22:35:13 +0200262 if( ret != 0 && ret > -128 )
263 ret = MBEDTLS_ERROR_ADD( MBEDTLS_ERR_DHM_MAKE_PARAMS_FAILED, ret );
264 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000265}
266
267/*
Hanno Becker8880e752017-10-04 13:15:08 +0100268 * Set prime modulus and generator
269 */
270int mbedtls_dhm_set_group( mbedtls_dhm_context *ctx,
271 const mbedtls_mpi *P,
272 const mbedtls_mpi *G )
273{
Janos Follath24eed8d2019-11-22 13:21:35 +0000274 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500275 DHM_VALIDATE_RET( ctx != NULL );
276 DHM_VALIDATE_RET( P != NULL );
277 DHM_VALIDATE_RET( G != NULL );
Hanno Becker8880e752017-10-04 13:15:08 +0100278
279 if( ( ret = mbedtls_mpi_copy( &ctx->P, P ) ) != 0 ||
280 ( ret = mbedtls_mpi_copy( &ctx->G, G ) ) != 0 )
281 {
Chris Jones9f7a6932021-04-14 12:12:09 +0100282 return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_DHM_SET_GROUP_FAILED, ret ) );
Hanno Becker8880e752017-10-04 13:15:08 +0100283 }
284
285 ctx->len = mbedtls_mpi_size( &ctx->P );
286 return( 0 );
287}
288
289/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000290 * Import the peer's public value G^Y
291 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200292int mbedtls_dhm_read_public( mbedtls_dhm_context *ctx,
Paul Bakker23986e52011-04-24 08:57:21 +0000293 const unsigned char *input, size_t ilen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000294{
Janos Follath24eed8d2019-11-22 13:21:35 +0000295 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500296 DHM_VALIDATE_RET( ctx != NULL );
297 DHM_VALIDATE_RET( input != NULL );
Paul Bakker5121ce52009-01-03 21:22:43 +0000298
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500299 if( ilen < 1 || ilen > ctx->len )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200300 return( MBEDTLS_ERR_DHM_BAD_INPUT_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +0000301
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200302 if( ( ret = mbedtls_mpi_read_binary( &ctx->GY, input, ilen ) ) != 0 )
Chris Jones9f7a6932021-04-14 12:12:09 +0100303 return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_DHM_READ_PUBLIC_FAILED, ret ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000304
305 return( 0 );
306}
307
308/*
309 * Create own private value X and export G^X
310 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200311int mbedtls_dhm_make_public( mbedtls_dhm_context *ctx, int x_size,
Paul Bakker23986e52011-04-24 08:57:21 +0000312 unsigned char *output, size_t olen,
Paul Bakkera3d195c2011-11-27 21:07:34 +0000313 int (*f_rng)(void *, unsigned char *, size_t),
314 void *p_rng )
Paul Bakker5121ce52009-01-03 21:22:43 +0000315{
Gilles Peskine0853bb22021-03-31 22:35:13 +0200316 int ret;
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500317 DHM_VALIDATE_RET( ctx != NULL );
318 DHM_VALIDATE_RET( output != NULL );
319 DHM_VALIDATE_RET( f_rng != NULL );
Paul Bakker5121ce52009-01-03 21:22:43 +0000320
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500321 if( olen < 1 || olen > ctx->len )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200322 return( MBEDTLS_ERR_DHM_BAD_INPUT_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +0000323
Gilles Peskine0853bb22021-03-31 22:35:13 +0200324 ret = dhm_make_common( ctx, x_size, f_rng, p_rng );
325 if( ret == MBEDTLS_ERR_DHM_MAKE_PARAMS_FAILED )
326 return( MBEDTLS_ERR_DHM_MAKE_PUBLIC_FAILED );
327 if( ret != 0 )
328 goto cleanup;
Paul Bakkerc47840e2011-02-20 16:37:30 +0000329
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200330 MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &ctx->GX, output, olen ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000331
332cleanup:
Gilles Peskine0853bb22021-03-31 22:35:13 +0200333 if( ret != 0 && ret > -128 )
334 ret = MBEDTLS_ERROR_ADD( MBEDTLS_ERR_DHM_MAKE_PUBLIC_FAILED, ret );
335 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000336}
337
Manuel Pégourié-Gonnard9f58c4b2020-06-25 12:34:58 +0200338
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
Gilles Peskineb4e815f2021-03-31 22:50:57 +0200385 /* Vi = random( 2, P-2 ) */
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 */