blob: e8055be71340e2cff8df24243a4df5cc200eb391 [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 Peskine8e38acc2021-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 Peskine8e38acc2021-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 Peskine8e38acc2021-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 Peskine8e38acc2021-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 Peskine17f1a262021-03-31 22:48:14 +0200152/*
Gilles Peskineda7ee012021-03-31 23:04:50 +0200153 * Pick a random R in the range [2, M-2] for blinding or key generation.
Gilles Peskine17f1a262021-03-31 22:48:14 +0200154 */
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{
Gilles Peskineda7ee012021-03-31 23:04:50 +0200158 int ret;
Gilles Peskine17f1a262021-03-31 22:48:14 +0200159
Gilles Peskineda7ee012021-03-31 23:04:50 +0200160 MBEDTLS_MPI_CHK( mbedtls_mpi_random( R, 3, M, f_rng, p_rng ) );
161 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( R, R, 1 ) );
Gilles Peskine17f1a262021-03-31 22:48:14 +0200162
163cleanup:
164 return( ret );
165}
166
Gilles Peskinecb660f22021-03-31 22:35:13 +0200167static int dhm_make_common( mbedtls_dhm_context *ctx, int x_size,
168 int (*f_rng)(void *, unsigned char *, size_t),
169 void *p_rng )
Paul Bakker5121ce52009-01-03 21:22:43 +0000170{
Gilles Peskine17f1a262021-03-31 22:48:14 +0200171 int ret = 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000172
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200173 if( mbedtls_mpi_cmp_int( &ctx->P, 0 ) == 0 )
174 return( MBEDTLS_ERR_DHM_BAD_INPUT_DATA );
Gilles Peskine17f1a262021-03-31 22:48:14 +0200175 if( x_size < 0 )
176 return( MBEDTLS_ERR_DHM_BAD_INPUT_DATA );
Paul Bakkerb5b20f12012-09-16 15:07:49 +0000177
Gilles Peskine17f1a262021-03-31 22:48:14 +0200178 if( (unsigned) x_size < mbedtls_mpi_size( &ctx->P ) )
Paul Bakkeraec37cb2012-04-26 18:59:59 +0000179 {
Ron Eldor7269fee2017-01-12 14:50:50 +0200180 MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( &ctx->X, x_size, f_rng, p_rng ) );
Paul Bakkeraec37cb2012-04-26 18:59:59 +0000181 }
Gilles Peskine17f1a262021-03-31 22:48:14 +0200182 else
183 {
184 /* Generate X as large as possible ( <= P - 2 ) */
185 ret = dhm_random_below( &ctx->X, &ctx->P, f_rng, p_rng );
186 if( ret == MBEDTLS_ERR_MPI_NOT_ACCEPTABLE )
187 return( MBEDTLS_ERR_DHM_MAKE_PARAMS_FAILED );
188 if( ret != 0 )
189 return( ret );
190 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000191
Paul Bakkerff7fe672010-07-18 09:45:05 +0000192 /*
193 * Calculate GX = G^X mod P
194 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200195 MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &ctx->GX, &ctx->G, &ctx->X,
Paul Bakker5121ce52009-01-03 21:22:43 +0000196 &ctx->P , &ctx->RP ) );
197
Paul Bakker345a6fe2011-02-28 21:20:02 +0000198 if( ( ret = dhm_check_range( &ctx->GX, &ctx->P ) ) != 0 )
Paul Bakkerc47840e2011-02-20 16:37:30 +0000199 return( ret );
200
Gilles Peskinecb660f22021-03-31 22:35:13 +0200201cleanup:
202 return( ret );
203}
204
205/*
206 * Setup and write the ServerKeyExchange parameters
207 */
208int mbedtls_dhm_make_params( mbedtls_dhm_context *ctx, int x_size,
209 unsigned char *output, size_t *olen,
210 int (*f_rng)(void *, unsigned char *, size_t),
211 void *p_rng )
212{
213 int ret;
214 size_t n1, n2, n3;
215 unsigned char *p;
216 DHM_VALIDATE_RET( ctx != NULL );
217 DHM_VALIDATE_RET( output != NULL );
218 DHM_VALIDATE_RET( olen != NULL );
219 DHM_VALIDATE_RET( f_rng != NULL );
220
221 ret = dhm_make_common( ctx, x_size, f_rng, p_rng );
222 if( ret != 0 )
223 goto cleanup;
224
Paul Bakker5121ce52009-01-03 21:22:43 +0000225 /*
226 * export P, G, GX
227 */
Hanno Beckerde6c1642017-10-02 15:03:15 +0100228#define DHM_MPI_EXPORT( X, n ) \
Hanno Beckere71ad122017-09-28 10:32:25 +0100229 do { \
Hanno Beckerde6c1642017-10-02 15:03:15 +0100230 MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( ( X ), \
231 p + 2, \
232 ( n ) ) ); \
233 *p++ = (unsigned char)( ( n ) >> 8 ); \
234 *p++ = (unsigned char)( ( n ) ); \
235 p += ( n ); \
Hanno Beckere71ad122017-09-28 10:32:25 +0100236 } while( 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000237
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200238 n1 = mbedtls_mpi_size( &ctx->P );
239 n2 = mbedtls_mpi_size( &ctx->G );
240 n3 = mbedtls_mpi_size( &ctx->GX );
Paul Bakker5121ce52009-01-03 21:22:43 +0000241
242 p = output;
243 DHM_MPI_EXPORT( &ctx->P , n1 );
244 DHM_MPI_EXPORT( &ctx->G , n2 );
245 DHM_MPI_EXPORT( &ctx->GX, n3 );
246
Hanno Beckere71ad122017-09-28 10:32:25 +0100247 *olen = p - output;
Paul Bakker5121ce52009-01-03 21:22:43 +0000248
249 ctx->len = n1;
250
251cleanup:
Gilles Peskinecb660f22021-03-31 22:35:13 +0200252 if( ret != 0 && ret > -128 )
253 ret = MBEDTLS_ERROR_ADD( MBEDTLS_ERR_DHM_MAKE_PARAMS_FAILED, ret );
254 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000255}
256
257/*
Hanno Becker8880e752017-10-04 13:15:08 +0100258 * Set prime modulus and generator
259 */
260int mbedtls_dhm_set_group( mbedtls_dhm_context *ctx,
261 const mbedtls_mpi *P,
262 const mbedtls_mpi *G )
263{
Janos Follath24eed8d2019-11-22 13:21:35 +0000264 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500265 DHM_VALIDATE_RET( ctx != NULL );
266 DHM_VALIDATE_RET( P != NULL );
267 DHM_VALIDATE_RET( G != NULL );
Hanno Becker8880e752017-10-04 13:15:08 +0100268
269 if( ( ret = mbedtls_mpi_copy( &ctx->P, P ) ) != 0 ||
270 ( ret = mbedtls_mpi_copy( &ctx->G, G ) ) != 0 )
271 {
Chris Jones9f7a6932021-04-14 12:12:09 +0100272 return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_DHM_SET_GROUP_FAILED, ret ) );
Hanno Becker8880e752017-10-04 13:15:08 +0100273 }
274
275 ctx->len = mbedtls_mpi_size( &ctx->P );
276 return( 0 );
277}
278
279/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000280 * Import the peer's public value G^Y
281 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200282int mbedtls_dhm_read_public( mbedtls_dhm_context *ctx,
Paul Bakker23986e52011-04-24 08:57:21 +0000283 const unsigned char *input, size_t ilen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000284{
Janos Follath24eed8d2019-11-22 13:21:35 +0000285 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500286 DHM_VALIDATE_RET( ctx != NULL );
287 DHM_VALIDATE_RET( input != NULL );
Paul Bakker5121ce52009-01-03 21:22:43 +0000288
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500289 if( ilen < 1 || ilen > ctx->len )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200290 return( MBEDTLS_ERR_DHM_BAD_INPUT_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +0000291
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200292 if( ( ret = mbedtls_mpi_read_binary( &ctx->GY, input, ilen ) ) != 0 )
Chris Jones9f7a6932021-04-14 12:12:09 +0100293 return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_DHM_READ_PUBLIC_FAILED, ret ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000294
295 return( 0 );
296}
297
298/*
299 * Create own private value X and export G^X
300 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200301int mbedtls_dhm_make_public( mbedtls_dhm_context *ctx, int x_size,
Paul Bakker23986e52011-04-24 08:57:21 +0000302 unsigned char *output, size_t olen,
Paul Bakkera3d195c2011-11-27 21:07:34 +0000303 int (*f_rng)(void *, unsigned char *, size_t),
304 void *p_rng )
Paul Bakker5121ce52009-01-03 21:22:43 +0000305{
Gilles Peskinecb660f22021-03-31 22:35:13 +0200306 int ret;
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500307 DHM_VALIDATE_RET( ctx != NULL );
308 DHM_VALIDATE_RET( output != NULL );
309 DHM_VALIDATE_RET( f_rng != NULL );
Paul Bakker5121ce52009-01-03 21:22:43 +0000310
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500311 if( olen < 1 || olen > ctx->len )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200312 return( MBEDTLS_ERR_DHM_BAD_INPUT_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +0000313
Gilles Peskinecb660f22021-03-31 22:35:13 +0200314 ret = dhm_make_common( ctx, x_size, f_rng, p_rng );
315 if( ret == MBEDTLS_ERR_DHM_MAKE_PARAMS_FAILED )
316 return( MBEDTLS_ERR_DHM_MAKE_PUBLIC_FAILED );
317 if( ret != 0 )
318 goto cleanup;
Paul Bakkerc47840e2011-02-20 16:37:30 +0000319
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200320 MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &ctx->GX, output, olen ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000321
322cleanup:
Gilles Peskinecb660f22021-03-31 22:35:13 +0200323 if( ret != 0 && ret > -128 )
324 ret = MBEDTLS_ERROR_ADD( MBEDTLS_ERR_DHM_MAKE_PUBLIC_FAILED, ret );
325 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000326}
327
Manuel Pégourié-Gonnard9f58c4b2020-06-25 12:34:58 +0200328
329/*
Manuel Pégourié-Gonnard143b5022013-09-04 16:29:59 +0200330 * Use the blinding method and optimisation suggested in section 10 of:
331 * KOCHER, Paul C. Timing attacks on implementations of Diffie-Hellman, RSA,
Manuel Pégourié-Gonnard998930a2015-04-03 13:48:06 +0200332 * DSS, and other systems. In : Advances in Cryptology-CRYPTO'96. Springer
Manuel Pégourié-Gonnard143b5022013-09-04 16:29:59 +0200333 * Berlin Heidelberg, 1996. p. 104-113.
334 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200335static int dhm_update_blinding( mbedtls_dhm_context *ctx,
Manuel Pégourié-Gonnard143b5022013-09-04 16:29:59 +0200336 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
337{
Manuel Pégourié-Gonnard9f58c4b2020-06-25 12:34:58 +0200338 int ret;
Manuel Pégourié-Gonnardaf721672020-06-25 12:47:22 +0200339 mbedtls_mpi R;
340
341 mbedtls_mpi_init( &R );
Manuel Pégourié-Gonnard143b5022013-09-04 16:29:59 +0200342
343 /*
Manuel Pégourié-Gonnard15d5de12013-09-17 11:34:11 +0200344 * Don't use any blinding the first time a particular X is used,
345 * but remember it to use blinding next time.
Manuel Pégourié-Gonnard143b5022013-09-04 16:29:59 +0200346 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200347 if( mbedtls_mpi_cmp_mpi( &ctx->X, &ctx->pX ) != 0 )
Manuel Pégourié-Gonnarded8a02b2013-09-04 16:39:03 +0200348 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200349 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &ctx->pX, &ctx->X ) );
350 MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &ctx->Vi, 1 ) );
351 MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &ctx->Vf, 1 ) );
Manuel Pégourié-Gonnarded8a02b2013-09-04 16:39:03 +0200352
Manuel Pégourié-Gonnard143b5022013-09-04 16:29:59 +0200353 return( 0 );
354 }
355
356 /*
Manuel Pégourié-Gonnard15d5de12013-09-17 11:34:11 +0200357 * Ok, we need blinding. Can we re-use existing values?
358 * If yes, just update them by squaring them.
Manuel Pégourié-Gonnard143b5022013-09-04 16:29:59 +0200359 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200360 if( mbedtls_mpi_cmp_int( &ctx->Vi, 1 ) != 0 )
Manuel Pégourié-Gonnard15d5de12013-09-17 11:34:11 +0200361 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200362 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &ctx->Vi, &ctx->Vi, &ctx->Vi ) );
363 MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &ctx->Vi, &ctx->Vi, &ctx->P ) );
Manuel Pégourié-Gonnard15d5de12013-09-17 11:34:11 +0200364
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200365 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &ctx->Vf, &ctx->Vf, &ctx->Vf ) );
366 MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &ctx->Vf, &ctx->Vf, &ctx->P ) );
Manuel Pégourié-Gonnard15d5de12013-09-17 11:34:11 +0200367
368 return( 0 );
369 }
370
371 /*
372 * We need to generate blinding values from scratch
373 */
374
Gilles Peskine7b2b66e2021-03-31 22:50:57 +0200375 /* Vi = random( 2, P-2 ) */
Manuel Pégourié-Gonnard9f58c4b2020-06-25 12:34:58 +0200376 MBEDTLS_MPI_CHK( dhm_random_below( &ctx->Vi, &ctx->P, f_rng, p_rng ) );
Manuel Pégourié-Gonnard15d5de12013-09-17 11:34:11 +0200377
Manuel Pégourié-Gonnardaf721672020-06-25 12:47:22 +0200378 /* Vf = Vi^-X mod P
379 * First compute Vi^-1 = R * (R Vi)^-1, (avoiding leaks from inv_mod),
380 * then elevate to the Xth power. */
381 MBEDTLS_MPI_CHK( dhm_random_below( &R, &ctx->P, f_rng, p_rng ) );
382 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &ctx->Vf, &ctx->Vi, &R ) );
383 MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &ctx->Vf, &ctx->Vf, &ctx->P ) );
384 MBEDTLS_MPI_CHK( mbedtls_mpi_inv_mod( &ctx->Vf, &ctx->Vf, &ctx->P ) );
385 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &ctx->Vf, &ctx->Vf, &R ) );
386 MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &ctx->Vf, &ctx->Vf, &ctx->P ) );
Manuel Pégourié-Gonnard15d5de12013-09-17 11:34:11 +0200387
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200388 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 +0200389
Manuel Pégourié-Gonnard143b5022013-09-04 16:29:59 +0200390cleanup:
Manuel Pégourié-Gonnardaf721672020-06-25 12:47:22 +0200391 mbedtls_mpi_free( &R );
392
Manuel Pégourié-Gonnard143b5022013-09-04 16:29:59 +0200393 return( ret );
394}
395
396/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000397 * Derive and export the shared secret (G^Y)^X mod P
398 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200399int mbedtls_dhm_calc_secret( mbedtls_dhm_context *ctx,
Manuel Pégourié-Gonnard33352052015-06-02 16:17:08 +0100400 unsigned char *output, size_t output_size, size_t *olen,
Manuel Pégourié-Gonnard2d627642013-09-04 14:22:07 +0200401 int (*f_rng)(void *, unsigned char *, size_t),
402 void *p_rng )
Paul Bakker5121ce52009-01-03 21:22:43 +0000403{
Janos Follath24eed8d2019-11-22 13:21:35 +0000404 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200405 mbedtls_mpi GYb;
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500406 DHM_VALIDATE_RET( ctx != NULL );
407 DHM_VALIDATE_RET( output != NULL );
408 DHM_VALIDATE_RET( olen != NULL );
Manuel Pégourié-Gonnard2d627642013-09-04 14:22:07 +0200409
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500410 if( output_size < ctx->len )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200411 return( MBEDTLS_ERR_DHM_BAD_INPUT_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +0000412
Paul Bakker345a6fe2011-02-28 21:20:02 +0000413 if( ( ret = dhm_check_range( &ctx->GY, &ctx->P ) ) != 0 )
Paul Bakkerc47840e2011-02-20 16:37:30 +0000414 return( ret );
415
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200416 mbedtls_mpi_init( &GYb );
Manuel Pégourié-Gonnard143b5022013-09-04 16:29:59 +0200417
418 /* Blind peer's value */
Manuel Pégourié-Gonnarded8a02b2013-09-04 16:39:03 +0200419 if( f_rng != NULL )
Manuel Pégourié-Gonnard143b5022013-09-04 16:29:59 +0200420 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200421 MBEDTLS_MPI_CHK( dhm_update_blinding( ctx, f_rng, p_rng ) );
422 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &GYb, &ctx->GY, &ctx->Vi ) );
423 MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &GYb, &GYb, &ctx->P ) );
Manuel Pégourié-Gonnard143b5022013-09-04 16:29:59 +0200424 }
425 else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200426 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &GYb, &ctx->GY ) );
Manuel Pégourié-Gonnard143b5022013-09-04 16:29:59 +0200427
428 /* Do modular exponentiation */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200429 MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &ctx->K, &GYb, &ctx->X,
Manuel Pégourié-Gonnard143b5022013-09-04 16:29:59 +0200430 &ctx->P, &ctx->RP ) );
431
432 /* Unblind secret value */
Manuel Pégourié-Gonnarded8a02b2013-09-04 16:39:03 +0200433 if( f_rng != NULL )
Manuel Pégourié-Gonnard143b5022013-09-04 16:29:59 +0200434 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200435 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &ctx->K, &ctx->K, &ctx->Vf ) );
436 MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &ctx->K, &ctx->K, &ctx->P ) );
Manuel Pégourié-Gonnard143b5022013-09-04 16:29:59 +0200437 }
438
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200439 *olen = mbedtls_mpi_size( &ctx->K );
Paul Bakker5121ce52009-01-03 21:22:43 +0000440
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200441 MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &ctx->K, output, *olen ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000442
443cleanup:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200444 mbedtls_mpi_free( &GYb );
Paul Bakker5121ce52009-01-03 21:22:43 +0000445
446 if( ret != 0 )
Chris Jones9f7a6932021-04-14 12:12:09 +0100447 return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_DHM_CALC_SECRET_FAILED, ret ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000448
449 return( 0 );
450}
451
452/*
453 * Free the components of a DHM key
454 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200455void mbedtls_dhm_free( mbedtls_dhm_context *ctx )
Paul Bakker5121ce52009-01-03 21:22:43 +0000456{
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500457 if( ctx == NULL )
458 return;
459
460 mbedtls_mpi_free( &ctx->pX );
461 mbedtls_mpi_free( &ctx->Vf );
462 mbedtls_mpi_free( &ctx->Vi );
463 mbedtls_mpi_free( &ctx->RP );
464 mbedtls_mpi_free( &ctx->K );
465 mbedtls_mpi_free( &ctx->GY );
466 mbedtls_mpi_free( &ctx->GX );
467 mbedtls_mpi_free( &ctx->X );
468 mbedtls_mpi_free( &ctx->G );
469 mbedtls_mpi_free( &ctx->P );
Manuel Pégourié-Gonnardb72b4ed2013-09-13 13:55:26 +0200470
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500471 mbedtls_platform_zeroize( ctx, sizeof( mbedtls_dhm_context ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000472}
473
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200474#if defined(MBEDTLS_ASN1_PARSE_C)
Paul Bakker40ce79f2013-09-15 17:43:54 +0200475/*
476 * Parse DHM parameters
477 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200478int mbedtls_dhm_parse_dhm( mbedtls_dhm_context *dhm, const unsigned char *dhmin,
Paul Bakkerb9e4e2c2014-05-01 14:18:25 +0200479 size_t dhminlen )
Paul Bakker40ce79f2013-09-15 17:43:54 +0200480{
Janos Follath24eed8d2019-11-22 13:21:35 +0000481 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker40ce79f2013-09-15 17:43:54 +0200482 size_t len;
483 unsigned char *p, *end;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200484#if defined(MBEDTLS_PEM_PARSE_C)
485 mbedtls_pem_context pem;
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500486#endif /* MBEDTLS_PEM_PARSE_C */
Paul Bakker40ce79f2013-09-15 17:43:54 +0200487
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500488 DHM_VALIDATE_RET( dhm != NULL );
489 DHM_VALIDATE_RET( dhmin != NULL );
490
491#if defined(MBEDTLS_PEM_PARSE_C)
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200492 mbedtls_pem_init( &pem );
Paul Bakker40ce79f2013-09-15 17:43:54 +0200493
Manuel Pégourié-Gonnard43b37cb2015-05-12 11:20:10 +0200494 /* Avoid calling mbedtls_pem_read_buffer() on non-null-terminated string */
Manuel Pégourié-Gonnard0ece0f92015-05-12 12:43:54 +0200495 if( dhminlen == 0 || dhmin[dhminlen - 1] != '\0' )
Manuel Pégourié-Gonnard43b37cb2015-05-12 11:20:10 +0200496 ret = MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT;
497 else
498 ret = mbedtls_pem_read_buffer( &pem,
499 "-----BEGIN DH PARAMETERS-----",
500 "-----END DH PARAMETERS-----",
501 dhmin, NULL, 0, &dhminlen );
Paul Bakker40ce79f2013-09-15 17:43:54 +0200502
503 if( ret == 0 )
504 {
505 /*
506 * Was PEM encoded
507 */
508 dhminlen = pem.buflen;
509 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200510 else if( ret != MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
Paul Bakker40ce79f2013-09-15 17:43:54 +0200511 goto exit;
512
513 p = ( ret == 0 ) ? pem.buf : (unsigned char *) dhmin;
514#else
515 p = (unsigned char *) dhmin;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200516#endif /* MBEDTLS_PEM_PARSE_C */
Paul Bakker40ce79f2013-09-15 17:43:54 +0200517 end = p + dhminlen;
518
519 /*
520 * DHParams ::= SEQUENCE {
Daniel Kahn Gillmor2ed81732015-04-03 13:09:24 -0400521 * prime INTEGER, -- P
522 * generator INTEGER, -- g
523 * privateValueLength INTEGER OPTIONAL
Paul Bakker40ce79f2013-09-15 17:43:54 +0200524 * }
525 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200526 if( ( ret = mbedtls_asn1_get_tag( &p, end, &len,
527 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
Paul Bakker40ce79f2013-09-15 17:43:54 +0200528 {
Chris Jones9f7a6932021-04-14 12:12:09 +0100529 ret = MBEDTLS_ERROR_ADD( MBEDTLS_ERR_DHM_INVALID_FORMAT, ret );
Paul Bakker40ce79f2013-09-15 17:43:54 +0200530 goto exit;
531 }
532
533 end = p + len;
534
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200535 if( ( ret = mbedtls_asn1_get_mpi( &p, end, &dhm->P ) ) != 0 ||
536 ( ret = mbedtls_asn1_get_mpi( &p, end, &dhm->G ) ) != 0 )
Paul Bakker40ce79f2013-09-15 17:43:54 +0200537 {
Chris Jones9f7a6932021-04-14 12:12:09 +0100538 ret = MBEDTLS_ERROR_ADD( MBEDTLS_ERR_DHM_INVALID_FORMAT, ret );
Paul Bakker40ce79f2013-09-15 17:43:54 +0200539 goto exit;
540 }
541
542 if( p != end )
543 {
Manuel Pégourié-Gonnardde9b3632015-04-17 20:06:31 +0200544 /* This might be the optional privateValueLength.
545 * If so, we can cleanly discard it */
546 mbedtls_mpi rec;
547 mbedtls_mpi_init( &rec );
548 ret = mbedtls_asn1_get_mpi( &p, end, &rec );
549 mbedtls_mpi_free( &rec );
Daniel Kahn Gillmor2ed81732015-04-03 13:09:24 -0400550 if ( ret != 0 )
551 {
Chris Jones9f7a6932021-04-14 12:12:09 +0100552 ret = MBEDTLS_ERROR_ADD( MBEDTLS_ERR_DHM_INVALID_FORMAT, ret );
Daniel Kahn Gillmor2ed81732015-04-03 13:09:24 -0400553 goto exit;
554 }
555 if ( p != end )
556 {
Chris Jones9f7a6932021-04-14 12:12:09 +0100557 ret = MBEDTLS_ERROR_ADD( MBEDTLS_ERR_DHM_INVALID_FORMAT,
558 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
Daniel Kahn Gillmor2ed81732015-04-03 13:09:24 -0400559 goto exit;
560 }
Paul Bakker40ce79f2013-09-15 17:43:54 +0200561 }
562
563 ret = 0;
564
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200565 dhm->len = mbedtls_mpi_size( &dhm->P );
Manuel Pégourié-Gonnard3fec2202014-03-29 16:42:38 +0100566
Paul Bakker40ce79f2013-09-15 17:43:54 +0200567exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200568#if defined(MBEDTLS_PEM_PARSE_C)
569 mbedtls_pem_free( &pem );
Paul Bakker40ce79f2013-09-15 17:43:54 +0200570#endif
571 if( ret != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200572 mbedtls_dhm_free( dhm );
Paul Bakker40ce79f2013-09-15 17:43:54 +0200573
574 return( ret );
575}
576
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200577#if defined(MBEDTLS_FS_IO)
Paul Bakker40ce79f2013-09-15 17:43:54 +0200578/*
579 * Load all data from a file into a given buffer.
Manuel Pégourié-Gonnard43b37cb2015-05-12 11:20:10 +0200580 *
581 * The file is expected to contain either PEM or DER encoded data.
582 * A terminating null byte is always appended. It is included in the announced
583 * length only if the data looks like it is PEM encoded.
Paul Bakker40ce79f2013-09-15 17:43:54 +0200584 */
585static int load_file( const char *path, unsigned char **buf, size_t *n )
586{
587 FILE *f;
588 long size;
589
590 if( ( f = fopen( path, "rb" ) ) == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200591 return( MBEDTLS_ERR_DHM_FILE_IO_ERROR );
Paul Bakker40ce79f2013-09-15 17:43:54 +0200592
593 fseek( f, 0, SEEK_END );
594 if( ( size = ftell( f ) ) == -1 )
595 {
596 fclose( f );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200597 return( MBEDTLS_ERR_DHM_FILE_IO_ERROR );
Paul Bakker40ce79f2013-09-15 17:43:54 +0200598 }
599 fseek( f, 0, SEEK_SET );
600
601 *n = (size_t) size;
602
603 if( *n + 1 == 0 ||
Manuel Pégourié-Gonnard7551cb92015-05-26 16:04:06 +0200604 ( *buf = mbedtls_calloc( 1, *n + 1 ) ) == NULL )
Paul Bakker40ce79f2013-09-15 17:43:54 +0200605 {
606 fclose( f );
Manuel Pégourié-Gonnard6a8ca332015-05-28 09:33:39 +0200607 return( MBEDTLS_ERR_DHM_ALLOC_FAILED );
Paul Bakker40ce79f2013-09-15 17:43:54 +0200608 }
609
610 if( fread( *buf, 1, *n, f ) != *n )
611 {
612 fclose( f );
Andres Amaya Garciabdbca7b2017-06-23 16:23:21 +0100613
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500614 mbedtls_platform_zeroize( *buf, *n + 1 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200615 mbedtls_free( *buf );
Andres Amaya Garciabdbca7b2017-06-23 16:23:21 +0100616
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200617 return( MBEDTLS_ERR_DHM_FILE_IO_ERROR );
Paul Bakker40ce79f2013-09-15 17:43:54 +0200618 }
619
620 fclose( f );
621
622 (*buf)[*n] = '\0';
623
Manuel Pégourié-Gonnard43b37cb2015-05-12 11:20:10 +0200624 if( strstr( (const char *) *buf, "-----BEGIN " ) != NULL )
625 ++*n;
626
Paul Bakker40ce79f2013-09-15 17:43:54 +0200627 return( 0 );
628}
629
630/*
631 * Load and parse DHM parameters
632 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200633int mbedtls_dhm_parse_dhmfile( mbedtls_dhm_context *dhm, const char *path )
Paul Bakker40ce79f2013-09-15 17:43:54 +0200634{
Janos Follath24eed8d2019-11-22 13:21:35 +0000635 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker40ce79f2013-09-15 17:43:54 +0200636 size_t n;
637 unsigned char *buf;
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500638 DHM_VALIDATE_RET( dhm != NULL );
639 DHM_VALIDATE_RET( path != NULL );
Paul Bakker40ce79f2013-09-15 17:43:54 +0200640
Paul Bakker66d5d072014-06-17 16:39:18 +0200641 if( ( ret = load_file( path, &buf, &n ) ) != 0 )
Paul Bakker40ce79f2013-09-15 17:43:54 +0200642 return( ret );
643
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200644 ret = mbedtls_dhm_parse_dhm( dhm, buf, n );
Paul Bakker40ce79f2013-09-15 17:43:54 +0200645
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500646 mbedtls_platform_zeroize( buf, n );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200647 mbedtls_free( buf );
Paul Bakker40ce79f2013-09-15 17:43:54 +0200648
649 return( ret );
650}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200651#endif /* MBEDTLS_FS_IO */
652#endif /* MBEDTLS_ASN1_PARSE_C */
nirekh0149762fa2017-12-25 06:46:48 +0000653#endif /* MBEDTLS_DHM_ALT */
Paul Bakker40ce79f2013-09-15 17:43:54 +0200654
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200655#if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +0000656
Hanno Becker8b0f9e62019-05-31 17:28:59 +0100657#if defined(MBEDTLS_PEM_PARSE_C)
Manuel Pégourié-Gonnard53585ee2015-06-25 08:52:25 +0200658static const char mbedtls_test_dhm_params[] =
659"-----BEGIN DH PARAMETERS-----\r\n"
660"MIGHAoGBAJ419DBEOgmQTzo5qXl5fQcN9TN455wkOL7052HzxxRVMyhYmwQcgJvh\r\n"
661"1sa18fyfR9OiVEMYglOpkqVoGLN7qd5aQNNi5W7/C+VBdHTBJcGZJyyP5B3qcz32\r\n"
662"9mLJKudlVudV0Qxk5qUJaPZ/xupz0NyoVpviuiBOI1gNi8ovSXWzAgEC\r\n"
663"-----END DH PARAMETERS-----\r\n";
Hanno Becker8b0f9e62019-05-31 17:28:59 +0100664#else /* MBEDTLS_PEM_PARSE_C */
665static const char mbedtls_test_dhm_params[] = {
666 0x30, 0x81, 0x87, 0x02, 0x81, 0x81, 0x00, 0x9e, 0x35, 0xf4, 0x30, 0x44,
667 0x3a, 0x09, 0x90, 0x4f, 0x3a, 0x39, 0xa9, 0x79, 0x79, 0x7d, 0x07, 0x0d,
668 0xf5, 0x33, 0x78, 0xe7, 0x9c, 0x24, 0x38, 0xbe, 0xf4, 0xe7, 0x61, 0xf3,
669 0xc7, 0x14, 0x55, 0x33, 0x28, 0x58, 0x9b, 0x04, 0x1c, 0x80, 0x9b, 0xe1,
670 0xd6, 0xc6, 0xb5, 0xf1, 0xfc, 0x9f, 0x47, 0xd3, 0xa2, 0x54, 0x43, 0x18,
671 0x82, 0x53, 0xa9, 0x92, 0xa5, 0x68, 0x18, 0xb3, 0x7b, 0xa9, 0xde, 0x5a,
672 0x40, 0xd3, 0x62, 0xe5, 0x6e, 0xff, 0x0b, 0xe5, 0x41, 0x74, 0x74, 0xc1,
673 0x25, 0xc1, 0x99, 0x27, 0x2c, 0x8f, 0xe4, 0x1d, 0xea, 0x73, 0x3d, 0xf6,
674 0xf6, 0x62, 0xc9, 0x2a, 0xe7, 0x65, 0x56, 0xe7, 0x55, 0xd1, 0x0c, 0x64,
675 0xe6, 0xa5, 0x09, 0x68, 0xf6, 0x7f, 0xc6, 0xea, 0x73, 0xd0, 0xdc, 0xa8,
676 0x56, 0x9b, 0xe2, 0xba, 0x20, 0x4e, 0x23, 0x58, 0x0d, 0x8b, 0xca, 0x2f,
677 0x49, 0x75, 0xb3, 0x02, 0x01, 0x02 };
678#endif /* MBEDTLS_PEM_PARSE_C */
Manuel Pégourié-Gonnard53585ee2015-06-25 08:52:25 +0200679
680static const size_t mbedtls_test_dhm_params_len = sizeof( mbedtls_test_dhm_params );
Paul Bakker40ce79f2013-09-15 17:43:54 +0200681
Paul Bakker5121ce52009-01-03 21:22:43 +0000682/*
683 * Checkup routine
684 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200685int mbedtls_dhm_self_test( int verbose )
Paul Bakker5121ce52009-01-03 21:22:43 +0000686{
Janos Follath24eed8d2019-11-22 13:21:35 +0000687 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200688 mbedtls_dhm_context dhm;
Paul Bakker40ce79f2013-09-15 17:43:54 +0200689
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200690 mbedtls_dhm_init( &dhm );
Paul Bakker8f870b02014-06-20 13:32:38 +0200691
Paul Bakker40ce79f2013-09-15 17:43:54 +0200692 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200693 mbedtls_printf( " DHM parameter load: " );
Paul Bakker40ce79f2013-09-15 17:43:54 +0200694
Manuel Pégourié-Gonnard53585ee2015-06-25 08:52:25 +0200695 if( ( ret = mbedtls_dhm_parse_dhm( &dhm,
696 (const unsigned char *) mbedtls_test_dhm_params,
697 mbedtls_test_dhm_params_len ) ) != 0 )
Paul Bakker40ce79f2013-09-15 17:43:54 +0200698 {
699 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200700 mbedtls_printf( "failed\n" );
Paul Bakker40ce79f2013-09-15 17:43:54 +0200701
Manuel Pégourié-Gonnardb196fc22014-07-09 16:53:29 +0200702 ret = 1;
Paul Bakker8f870b02014-06-20 13:32:38 +0200703 goto exit;
Paul Bakker40ce79f2013-09-15 17:43:54 +0200704 }
705
706 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200707 mbedtls_printf( "passed\n\n" );
Paul Bakker40ce79f2013-09-15 17:43:54 +0200708
Paul Bakker8f870b02014-06-20 13:32:38 +0200709exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200710 mbedtls_dhm_free( &dhm );
Paul Bakker40ce79f2013-09-15 17:43:54 +0200711
Paul Bakker8f870b02014-06-20 13:32:38 +0200712 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000713}
714
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200715#endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +0000716
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200717#endif /* MBEDTLS_DHM_C */