blob: 387f5beda677516c2dcb55ec93a92dc589b54c8c [file] [log] [blame]
Paul Bakker5121ce52009-01-03 21:22:43 +00001/*
2 * Diffie-Hellman-Merkle key exchange
3 *
Manuel Pégourié-Gonnard6fb81872015-07-27 11:11:48 +02004 * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
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 Bakkerb96f1542010-07-18 20:36:00 +000018 *
Manuel Pégourié-Gonnardfe446432015-03-06 13:17:10 +000019 * This file is part of mbed TLS (https://tls.mbed.org)
Paul Bakker5121ce52009-01-03 21:22:43 +000020 */
21/*
Simon Butcherbdae02c2016-01-20 00:44:42 +000022 * The following sources were referenced in the design of this implementation
23 * of the Diffie-Hellman-Merkle algorithm:
Paul Bakker5121ce52009-01-03 21:22:43 +000024 *
Simon Butcherbdae02c2016-01-20 00:44:42 +000025 * [1] Handbook of Applied Cryptography - 1997, Chapter 12
26 * Menezes, van Oorschot and Vanstone
27 *
Paul Bakker5121ce52009-01-03 21:22:43 +000028 */
29
Gilles Peskinedb09ef62020-06-03 01:43:33 +020030#include "common.h"
Paul Bakker5121ce52009-01-03 21:22:43 +000031
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020032#if defined(MBEDTLS_DHM_C)
Paul Bakker5121ce52009-01-03 21:22:43 +000033
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000034#include "mbedtls/dhm.h"
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -050035#include "mbedtls/platform_util.h"
Janos Follath24eed8d2019-11-22 13:21:35 +000036#include "mbedtls/error.h"
Paul Bakker5121ce52009-01-03 21:22:43 +000037
Rich Evans00ab4702015-02-06 13:43:58 +000038#include <string.h>
39
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020040#if defined(MBEDTLS_PEM_PARSE_C)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000041#include "mbedtls/pem.h"
Paul Bakker40ce79f2013-09-15 17:43:54 +020042#endif
43
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020044#if defined(MBEDTLS_ASN1_PARSE_C)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000045#include "mbedtls/asn1.h"
Paul Bakker40ce79f2013-09-15 17:43:54 +020046#endif
47
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020048#if defined(MBEDTLS_PLATFORM_C)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000049#include "mbedtls/platform.h"
Paul Bakker40ce79f2013-09-15 17:43:54 +020050#else
51#include <stdlib.h>
Manuel Pégourié-Gonnard981732b2015-02-17 15:46:45 +000052#include <stdio.h>
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020053#define mbedtls_printf printf
Manuel Pégourié-Gonnard7551cb92015-05-26 16:04:06 +020054#define mbedtls_calloc calloc
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020055#define mbedtls_free free
Paul Bakker40ce79f2013-09-15 17:43:54 +020056#endif
57
Reuven Levin1f35ca92017-12-07 10:09:32 +000058#if !defined(MBEDTLS_DHM_ALT)
Paul Bakker34617722014-06-13 17:20:13 +020059
Andrzej Kurekc470b6b2019-01-31 08:20:20 -050060#define DHM_VALIDATE_RET( cond ) \
61 MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_DHM_BAD_INPUT_DATA )
62#define DHM_VALIDATE( cond ) \
63 MBEDTLS_INTERNAL_VALIDATE( cond )
64
Paul Bakker5121ce52009-01-03 21:22:43 +000065/*
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020066 * helper to validate the mbedtls_mpi size and import it
Paul Bakker5121ce52009-01-03 21:22:43 +000067 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020068static int dhm_read_bignum( mbedtls_mpi *X,
Paul Bakker5121ce52009-01-03 21:22:43 +000069 unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +000070 const unsigned char *end )
Paul Bakker5121ce52009-01-03 21:22:43 +000071{
72 int ret, n;
73
74 if( end - *p < 2 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020075 return( MBEDTLS_ERR_DHM_BAD_INPUT_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +000076
77 n = ( (*p)[0] << 8 ) | (*p)[1];
78 (*p) += 2;
79
80 if( (int)( end - *p ) < n )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020081 return( MBEDTLS_ERR_DHM_BAD_INPUT_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +000082
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020083 if( ( ret = mbedtls_mpi_read_binary( X, *p, n ) ) != 0 )
84 return( MBEDTLS_ERR_DHM_READ_PARAMS_FAILED + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +000085
86 (*p) += n;
87
88 return( 0 );
89}
90
91/*
Paul Bakkeraec37cb2012-04-26 18:59:59 +000092 * Verify sanity of parameter with regards to P
Paul Bakker345a6fe2011-02-28 21:20:02 +000093 *
Paul Bakkeraec37cb2012-04-26 18:59:59 +000094 * Parameter should be: 2 <= public_param <= P - 2
Paul Bakker345a6fe2011-02-28 21:20:02 +000095 *
Janos Follathaa325d72017-09-20 15:33:24 +010096 * This means that we need to return an error if
Janos Follath1ad1c6d2017-09-21 09:02:11 +010097 * public_param < 2 or public_param > P-2
Janos Follathaa325d72017-09-20 15:33:24 +010098 *
Paul Bakker345a6fe2011-02-28 21:20:02 +000099 * For more information on the attack, see:
100 * http://www.cl.cam.ac.uk/~rja14/Papers/psandqs.pdf
101 * http://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2005-2643
Paul Bakkerc47840e2011-02-20 16:37:30 +0000102 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200103static int dhm_check_range( const mbedtls_mpi *param, const mbedtls_mpi *P )
Paul Bakkerc47840e2011-02-20 16:37:30 +0000104{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200105 mbedtls_mpi L, U;
Janos Follathaa325d72017-09-20 15:33:24 +0100106 int ret = 0;
Paul Bakkerc47840e2011-02-20 16:37:30 +0000107
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200108 mbedtls_mpi_init( &L ); mbedtls_mpi_init( &U );
Paul Bakker3d8fb632014-04-17 12:42:41 +0200109
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200110 MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &L, 2 ) );
111 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &U, P, 2 ) );
Paul Bakkerc47840e2011-02-20 16:37:30 +0000112
Janos Follathaa325d72017-09-20 15:33:24 +0100113 if( mbedtls_mpi_cmp_mpi( param, &L ) < 0 ||
114 mbedtls_mpi_cmp_mpi( param, &U ) > 0 )
Paul Bakkerc47840e2011-02-20 16:37:30 +0000115 {
Janos Follathaa325d72017-09-20 15:33:24 +0100116 ret = MBEDTLS_ERR_DHM_BAD_INPUT_DATA;
Paul Bakkerc47840e2011-02-20 16:37:30 +0000117 }
118
Paul Bakker3d8fb632014-04-17 12:42:41 +0200119cleanup:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200120 mbedtls_mpi_free( &L ); mbedtls_mpi_free( &U );
Paul Bakker345a6fe2011-02-28 21:20:02 +0000121 return( ret );
Paul Bakkerc47840e2011-02-20 16:37:30 +0000122}
123
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200124void mbedtls_dhm_init( mbedtls_dhm_context *ctx )
Paul Bakker8f870b02014-06-20 13:32:38 +0200125{
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500126 DHM_VALIDATE( ctx != NULL );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200127 memset( ctx, 0, sizeof( mbedtls_dhm_context ) );
Paul Bakker8f870b02014-06-20 13:32:38 +0200128}
129
Paul Bakkerc47840e2011-02-20 16:37:30 +0000130/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000131 * Parse the ServerKeyExchange parameters
132 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200133int mbedtls_dhm_read_params( mbedtls_dhm_context *ctx,
Paul Bakker5121ce52009-01-03 21:22:43 +0000134 unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000135 const unsigned char *end )
Paul Bakker5121ce52009-01-03 21:22:43 +0000136{
Janos Follath24eed8d2019-11-22 13:21:35 +0000137 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500138 DHM_VALIDATE_RET( ctx != NULL );
139 DHM_VALIDATE_RET( p != NULL && *p != NULL );
140 DHM_VALIDATE_RET( end != NULL );
Paul Bakker5121ce52009-01-03 21:22:43 +0000141
Paul Bakker5121ce52009-01-03 21:22:43 +0000142 if( ( ret = dhm_read_bignum( &ctx->P, p, end ) ) != 0 ||
143 ( ret = dhm_read_bignum( &ctx->G, p, end ) ) != 0 ||
144 ( ret = dhm_read_bignum( &ctx->GY, p, end ) ) != 0 )
145 return( ret );
146
Paul Bakker345a6fe2011-02-28 21:20:02 +0000147 if( ( ret = dhm_check_range( &ctx->GY, &ctx->P ) ) != 0 )
148 return( ret );
149
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200150 ctx->len = mbedtls_mpi_size( &ctx->P );
Paul Bakker5121ce52009-01-03 21:22:43 +0000151
Paul Bakker5121ce52009-01-03 21:22:43 +0000152 return( 0 );
153}
154
155/*
156 * Setup and write the ServerKeyExchange parameters
157 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200158int mbedtls_dhm_make_params( mbedtls_dhm_context *ctx, int x_size,
Paul Bakker23986e52011-04-24 08:57:21 +0000159 unsigned char *output, size_t *olen,
Paul Bakkera3d195c2011-11-27 21:07:34 +0000160 int (*f_rng)(void *, unsigned char *, size_t),
161 void *p_rng )
Paul Bakker5121ce52009-01-03 21:22:43 +0000162{
Paul Bakkeraec37cb2012-04-26 18:59:59 +0000163 int ret, count = 0;
Paul Bakker23986e52011-04-24 08:57:21 +0000164 size_t n1, n2, n3;
Paul Bakker5121ce52009-01-03 21:22:43 +0000165 unsigned char *p;
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500166 DHM_VALIDATE_RET( ctx != NULL );
167 DHM_VALIDATE_RET( output != NULL );
168 DHM_VALIDATE_RET( olen != NULL );
169 DHM_VALIDATE_RET( f_rng != NULL );
Paul Bakker5121ce52009-01-03 21:22:43 +0000170
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200171 if( mbedtls_mpi_cmp_int( &ctx->P, 0 ) == 0 )
172 return( MBEDTLS_ERR_DHM_BAD_INPUT_DATA );
Paul Bakkerb5b20f12012-09-16 15:07:49 +0000173
Paul Bakker5121ce52009-01-03 21:22:43 +0000174 /*
Paul Bakkerff7fe672010-07-18 09:45:05 +0000175 * Generate X as large as possible ( < P )
Paul Bakker5121ce52009-01-03 21:22:43 +0000176 */
Paul Bakkeraec37cb2012-04-26 18:59:59 +0000177 do
178 {
Ron Eldor7269fee2017-01-12 14:50:50 +0200179 MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( &ctx->X, x_size, f_rng, p_rng ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000180
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200181 while( mbedtls_mpi_cmp_mpi( &ctx->X, &ctx->P ) >= 0 )
182 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &ctx->X, 1 ) );
Paul Bakkeraec37cb2012-04-26 18:59:59 +0000183
184 if( count++ > 10 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200185 return( MBEDTLS_ERR_DHM_MAKE_PARAMS_FAILED );
Paul Bakkeraec37cb2012-04-26 18:59:59 +0000186 }
187 while( dhm_check_range( &ctx->X, &ctx->P ) != 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000188
Paul Bakkerff7fe672010-07-18 09:45:05 +0000189 /*
190 * Calculate GX = G^X mod P
191 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200192 MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &ctx->GX, &ctx->G, &ctx->X,
Paul Bakker5121ce52009-01-03 21:22:43 +0000193 &ctx->P , &ctx->RP ) );
194
Paul Bakker345a6fe2011-02-28 21:20:02 +0000195 if( ( ret = dhm_check_range( &ctx->GX, &ctx->P ) ) != 0 )
Paul Bakkerc47840e2011-02-20 16:37:30 +0000196 return( ret );
197
Paul Bakker5121ce52009-01-03 21:22:43 +0000198 /*
199 * export P, G, GX
200 */
Hanno Beckerde6c1642017-10-02 15:03:15 +0100201#define DHM_MPI_EXPORT( X, n ) \
Hanno Beckere71ad122017-09-28 10:32:25 +0100202 do { \
Hanno Beckerde6c1642017-10-02 15:03:15 +0100203 MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( ( X ), \
204 p + 2, \
205 ( n ) ) ); \
206 *p++ = (unsigned char)( ( n ) >> 8 ); \
207 *p++ = (unsigned char)( ( n ) ); \
208 p += ( n ); \
Hanno Beckere71ad122017-09-28 10:32:25 +0100209 } while( 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000210
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200211 n1 = mbedtls_mpi_size( &ctx->P );
212 n2 = mbedtls_mpi_size( &ctx->G );
213 n3 = mbedtls_mpi_size( &ctx->GX );
Paul Bakker5121ce52009-01-03 21:22:43 +0000214
215 p = output;
216 DHM_MPI_EXPORT( &ctx->P , n1 );
217 DHM_MPI_EXPORT( &ctx->G , n2 );
218 DHM_MPI_EXPORT( &ctx->GX, n3 );
219
Hanno Beckere71ad122017-09-28 10:32:25 +0100220 *olen = p - output;
Paul Bakker5121ce52009-01-03 21:22:43 +0000221
222 ctx->len = n1;
223
224cleanup:
225
226 if( ret != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200227 return( MBEDTLS_ERR_DHM_MAKE_PARAMS_FAILED + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000228
229 return( 0 );
230}
231
232/*
Hanno Becker8880e752017-10-04 13:15:08 +0100233 * Set prime modulus and generator
234 */
235int mbedtls_dhm_set_group( mbedtls_dhm_context *ctx,
236 const mbedtls_mpi *P,
237 const mbedtls_mpi *G )
238{
Janos Follath24eed8d2019-11-22 13:21:35 +0000239 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500240 DHM_VALIDATE_RET( ctx != NULL );
241 DHM_VALIDATE_RET( P != NULL );
242 DHM_VALIDATE_RET( G != NULL );
Hanno Becker8880e752017-10-04 13:15:08 +0100243
244 if( ( ret = mbedtls_mpi_copy( &ctx->P, P ) ) != 0 ||
245 ( ret = mbedtls_mpi_copy( &ctx->G, G ) ) != 0 )
246 {
247 return( MBEDTLS_ERR_DHM_SET_GROUP_FAILED + ret );
248 }
249
250 ctx->len = mbedtls_mpi_size( &ctx->P );
251 return( 0 );
252}
253
254/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000255 * Import the peer's public value G^Y
256 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200257int mbedtls_dhm_read_public( mbedtls_dhm_context *ctx,
Paul Bakker23986e52011-04-24 08:57:21 +0000258 const unsigned char *input, size_t ilen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000259{
Janos Follath24eed8d2019-11-22 13:21:35 +0000260 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500261 DHM_VALIDATE_RET( ctx != NULL );
262 DHM_VALIDATE_RET( input != NULL );
Paul Bakker5121ce52009-01-03 21:22:43 +0000263
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500264 if( ilen < 1 || ilen > ctx->len )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200265 return( MBEDTLS_ERR_DHM_BAD_INPUT_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +0000266
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200267 if( ( ret = mbedtls_mpi_read_binary( &ctx->GY, input, ilen ) ) != 0 )
268 return( MBEDTLS_ERR_DHM_READ_PUBLIC_FAILED + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000269
270 return( 0 );
271}
272
273/*
274 * Create own private value X and export G^X
275 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200276int mbedtls_dhm_make_public( mbedtls_dhm_context *ctx, int x_size,
Paul Bakker23986e52011-04-24 08:57:21 +0000277 unsigned char *output, size_t olen,
Paul Bakkera3d195c2011-11-27 21:07:34 +0000278 int (*f_rng)(void *, unsigned char *, size_t),
279 void *p_rng )
Paul Bakker5121ce52009-01-03 21:22:43 +0000280{
Paul Bakkeraec37cb2012-04-26 18:59:59 +0000281 int ret, count = 0;
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500282 DHM_VALIDATE_RET( ctx != NULL );
283 DHM_VALIDATE_RET( output != NULL );
284 DHM_VALIDATE_RET( f_rng != NULL );
Paul Bakker5121ce52009-01-03 21:22:43 +0000285
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500286 if( olen < 1 || olen > ctx->len )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200287 return( MBEDTLS_ERR_DHM_BAD_INPUT_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +0000288
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200289 if( mbedtls_mpi_cmp_int( &ctx->P, 0 ) == 0 )
290 return( MBEDTLS_ERR_DHM_BAD_INPUT_DATA );
Paul Bakkerb5b20f12012-09-16 15:07:49 +0000291
Paul Bakker5121ce52009-01-03 21:22:43 +0000292 /*
293 * generate X and calculate GX = G^X mod P
294 */
Paul Bakkeraec37cb2012-04-26 18:59:59 +0000295 do
296 {
Ron Eldor7269fee2017-01-12 14:50:50 +0200297 MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( &ctx->X, x_size, f_rng, p_rng ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000298
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200299 while( mbedtls_mpi_cmp_mpi( &ctx->X, &ctx->P ) >= 0 )
300 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &ctx->X, 1 ) );
Paul Bakkeraec37cb2012-04-26 18:59:59 +0000301
302 if( count++ > 10 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200303 return( MBEDTLS_ERR_DHM_MAKE_PUBLIC_FAILED );
Paul Bakkeraec37cb2012-04-26 18:59:59 +0000304 }
305 while( dhm_check_range( &ctx->X, &ctx->P ) != 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000306
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200307 MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &ctx->GX, &ctx->G, &ctx->X,
Paul Bakker5121ce52009-01-03 21:22:43 +0000308 &ctx->P , &ctx->RP ) );
309
Paul Bakker345a6fe2011-02-28 21:20:02 +0000310 if( ( ret = dhm_check_range( &ctx->GX, &ctx->P ) ) != 0 )
311 return( ret );
Paul Bakkerc47840e2011-02-20 16:37:30 +0000312
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200313 MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &ctx->GX, output, olen ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000314
315cleanup:
316
317 if( ret != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200318 return( MBEDTLS_ERR_DHM_MAKE_PUBLIC_FAILED + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000319
320 return( 0 );
321}
322
323/*
Manuel Pégourié-Gonnard143b5022013-09-04 16:29:59 +0200324 * Use the blinding method and optimisation suggested in section 10 of:
325 * KOCHER, Paul C. Timing attacks on implementations of Diffie-Hellman, RSA,
Manuel Pégourié-Gonnard998930a2015-04-03 13:48:06 +0200326 * DSS, and other systems. In : Advances in Cryptology-CRYPTO'96. Springer
Manuel Pégourié-Gonnard143b5022013-09-04 16:29:59 +0200327 * Berlin Heidelberg, 1996. p. 104-113.
328 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200329static int dhm_update_blinding( mbedtls_dhm_context *ctx,
Manuel Pégourié-Gonnard143b5022013-09-04 16:29:59 +0200330 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
331{
332 int ret, count;
333
334 /*
Manuel Pégourié-Gonnard15d5de12013-09-17 11:34:11 +0200335 * Don't use any blinding the first time a particular X is used,
336 * but remember it to use blinding next time.
Manuel Pégourié-Gonnard143b5022013-09-04 16:29:59 +0200337 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200338 if( mbedtls_mpi_cmp_mpi( &ctx->X, &ctx->pX ) != 0 )
Manuel Pégourié-Gonnarded8a02b2013-09-04 16:39:03 +0200339 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200340 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &ctx->pX, &ctx->X ) );
341 MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &ctx->Vi, 1 ) );
342 MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &ctx->Vf, 1 ) );
Manuel Pégourié-Gonnarded8a02b2013-09-04 16:39:03 +0200343
Manuel Pégourié-Gonnard143b5022013-09-04 16:29:59 +0200344 return( 0 );
345 }
346
347 /*
Manuel Pégourié-Gonnard15d5de12013-09-17 11:34:11 +0200348 * Ok, we need blinding. Can we re-use existing values?
349 * If yes, just update them by squaring them.
Manuel Pégourié-Gonnard143b5022013-09-04 16:29:59 +0200350 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200351 if( mbedtls_mpi_cmp_int( &ctx->Vi, 1 ) != 0 )
Manuel Pégourié-Gonnard15d5de12013-09-17 11:34:11 +0200352 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200353 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &ctx->Vi, &ctx->Vi, &ctx->Vi ) );
354 MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &ctx->Vi, &ctx->Vi, &ctx->P ) );
Manuel Pégourié-Gonnard15d5de12013-09-17 11:34:11 +0200355
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200356 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &ctx->Vf, &ctx->Vf, &ctx->Vf ) );
357 MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &ctx->Vf, &ctx->Vf, &ctx->P ) );
Manuel Pégourié-Gonnard15d5de12013-09-17 11:34:11 +0200358
359 return( 0 );
360 }
361
362 /*
363 * We need to generate blinding values from scratch
364 */
365
366 /* Vi = random( 2, P-1 ) */
367 count = 0;
368 do
369 {
Ron Eldor7269fee2017-01-12 14:50:50 +0200370 MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( &ctx->Vi, mbedtls_mpi_size( &ctx->P ), f_rng, p_rng ) );
Manuel Pégourié-Gonnard15d5de12013-09-17 11:34:11 +0200371
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200372 while( mbedtls_mpi_cmp_mpi( &ctx->Vi, &ctx->P ) >= 0 )
373 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &ctx->Vi, 1 ) );
Manuel Pégourié-Gonnard15d5de12013-09-17 11:34:11 +0200374
375 if( count++ > 10 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200376 return( MBEDTLS_ERR_MPI_NOT_ACCEPTABLE );
Manuel Pégourié-Gonnard15d5de12013-09-17 11:34:11 +0200377 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200378 while( mbedtls_mpi_cmp_int( &ctx->Vi, 1 ) <= 0 );
Manuel Pégourié-Gonnard143b5022013-09-04 16:29:59 +0200379
Manuel Pégourié-Gonnard143b5022013-09-04 16:29:59 +0200380 /* Vf = Vi^-X mod P */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200381 MBEDTLS_MPI_CHK( mbedtls_mpi_inv_mod( &ctx->Vf, &ctx->Vi, &ctx->P ) );
382 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 +0200383
Manuel Pégourié-Gonnard143b5022013-09-04 16:29:59 +0200384cleanup:
385 return( ret );
386}
387
388/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000389 * Derive and export the shared secret (G^Y)^X mod P
390 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200391int mbedtls_dhm_calc_secret( mbedtls_dhm_context *ctx,
Manuel Pégourié-Gonnard33352052015-06-02 16:17:08 +0100392 unsigned char *output, size_t output_size, size_t *olen,
Manuel Pégourié-Gonnard2d627642013-09-04 14:22:07 +0200393 int (*f_rng)(void *, unsigned char *, size_t),
394 void *p_rng )
Paul Bakker5121ce52009-01-03 21:22:43 +0000395{
Janos Follath24eed8d2019-11-22 13:21:35 +0000396 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200397 mbedtls_mpi GYb;
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500398 DHM_VALIDATE_RET( ctx != NULL );
399 DHM_VALIDATE_RET( output != NULL );
400 DHM_VALIDATE_RET( olen != NULL );
Manuel Pégourié-Gonnard2d627642013-09-04 14:22:07 +0200401
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500402 if( output_size < ctx->len )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200403 return( MBEDTLS_ERR_DHM_BAD_INPUT_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +0000404
Paul Bakker345a6fe2011-02-28 21:20:02 +0000405 if( ( ret = dhm_check_range( &ctx->GY, &ctx->P ) ) != 0 )
Paul Bakkerc47840e2011-02-20 16:37:30 +0000406 return( ret );
407
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200408 mbedtls_mpi_init( &GYb );
Manuel Pégourié-Gonnard143b5022013-09-04 16:29:59 +0200409
410 /* Blind peer's value */
Manuel Pégourié-Gonnarded8a02b2013-09-04 16:39:03 +0200411 if( f_rng != NULL )
Manuel Pégourié-Gonnard143b5022013-09-04 16:29:59 +0200412 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200413 MBEDTLS_MPI_CHK( dhm_update_blinding( ctx, f_rng, p_rng ) );
414 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &GYb, &ctx->GY, &ctx->Vi ) );
415 MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &GYb, &GYb, &ctx->P ) );
Manuel Pégourié-Gonnard143b5022013-09-04 16:29:59 +0200416 }
417 else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200418 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &GYb, &ctx->GY ) );
Manuel Pégourié-Gonnard143b5022013-09-04 16:29:59 +0200419
420 /* Do modular exponentiation */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200421 MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &ctx->K, &GYb, &ctx->X,
Manuel Pégourié-Gonnard143b5022013-09-04 16:29:59 +0200422 &ctx->P, &ctx->RP ) );
423
424 /* Unblind secret value */
Manuel Pégourié-Gonnarded8a02b2013-09-04 16:39:03 +0200425 if( f_rng != NULL )
Manuel Pégourié-Gonnard143b5022013-09-04 16:29:59 +0200426 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200427 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &ctx->K, &ctx->K, &ctx->Vf ) );
428 MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &ctx->K, &ctx->K, &ctx->P ) );
Manuel Pégourié-Gonnard143b5022013-09-04 16:29:59 +0200429 }
430
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200431 *olen = mbedtls_mpi_size( &ctx->K );
Paul Bakker5121ce52009-01-03 21:22:43 +0000432
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200433 MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &ctx->K, output, *olen ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000434
435cleanup:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200436 mbedtls_mpi_free( &GYb );
Paul Bakker5121ce52009-01-03 21:22:43 +0000437
438 if( ret != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200439 return( MBEDTLS_ERR_DHM_CALC_SECRET_FAILED + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000440
441 return( 0 );
442}
443
444/*
445 * Free the components of a DHM key
446 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200447void mbedtls_dhm_free( mbedtls_dhm_context *ctx )
Paul Bakker5121ce52009-01-03 21:22:43 +0000448{
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500449 if( ctx == NULL )
450 return;
451
452 mbedtls_mpi_free( &ctx->pX );
453 mbedtls_mpi_free( &ctx->Vf );
454 mbedtls_mpi_free( &ctx->Vi );
455 mbedtls_mpi_free( &ctx->RP );
456 mbedtls_mpi_free( &ctx->K );
457 mbedtls_mpi_free( &ctx->GY );
458 mbedtls_mpi_free( &ctx->GX );
459 mbedtls_mpi_free( &ctx->X );
460 mbedtls_mpi_free( &ctx->G );
461 mbedtls_mpi_free( &ctx->P );
Manuel Pégourié-Gonnardb72b4ed2013-09-13 13:55:26 +0200462
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500463 mbedtls_platform_zeroize( ctx, sizeof( mbedtls_dhm_context ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000464}
465
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200466#if defined(MBEDTLS_ASN1_PARSE_C)
Paul Bakker40ce79f2013-09-15 17:43:54 +0200467/*
468 * Parse DHM parameters
469 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200470int mbedtls_dhm_parse_dhm( mbedtls_dhm_context *dhm, const unsigned char *dhmin,
Paul Bakkerb9e4e2c2014-05-01 14:18:25 +0200471 size_t dhminlen )
Paul Bakker40ce79f2013-09-15 17:43:54 +0200472{
Janos Follath24eed8d2019-11-22 13:21:35 +0000473 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker40ce79f2013-09-15 17:43:54 +0200474 size_t len;
475 unsigned char *p, *end;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200476#if defined(MBEDTLS_PEM_PARSE_C)
477 mbedtls_pem_context pem;
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500478#endif /* MBEDTLS_PEM_PARSE_C */
Paul Bakker40ce79f2013-09-15 17:43:54 +0200479
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500480 DHM_VALIDATE_RET( dhm != NULL );
481 DHM_VALIDATE_RET( dhmin != NULL );
482
483#if defined(MBEDTLS_PEM_PARSE_C)
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200484 mbedtls_pem_init( &pem );
Paul Bakker40ce79f2013-09-15 17:43:54 +0200485
Manuel Pégourié-Gonnard43b37cb2015-05-12 11:20:10 +0200486 /* Avoid calling mbedtls_pem_read_buffer() on non-null-terminated string */
Manuel Pégourié-Gonnard0ece0f92015-05-12 12:43:54 +0200487 if( dhminlen == 0 || dhmin[dhminlen - 1] != '\0' )
Manuel Pégourié-Gonnard43b37cb2015-05-12 11:20:10 +0200488 ret = MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT;
489 else
490 ret = mbedtls_pem_read_buffer( &pem,
491 "-----BEGIN DH PARAMETERS-----",
492 "-----END DH PARAMETERS-----",
493 dhmin, NULL, 0, &dhminlen );
Paul Bakker40ce79f2013-09-15 17:43:54 +0200494
495 if( ret == 0 )
496 {
497 /*
498 * Was PEM encoded
499 */
500 dhminlen = pem.buflen;
501 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200502 else if( ret != MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
Paul Bakker40ce79f2013-09-15 17:43:54 +0200503 goto exit;
504
505 p = ( ret == 0 ) ? pem.buf : (unsigned char *) dhmin;
506#else
507 p = (unsigned char *) dhmin;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200508#endif /* MBEDTLS_PEM_PARSE_C */
Paul Bakker40ce79f2013-09-15 17:43:54 +0200509 end = p + dhminlen;
510
511 /*
512 * DHParams ::= SEQUENCE {
Daniel Kahn Gillmor2ed81732015-04-03 13:09:24 -0400513 * prime INTEGER, -- P
514 * generator INTEGER, -- g
515 * privateValueLength INTEGER OPTIONAL
Paul Bakker40ce79f2013-09-15 17:43:54 +0200516 * }
517 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200518 if( ( ret = mbedtls_asn1_get_tag( &p, end, &len,
519 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
Paul Bakker40ce79f2013-09-15 17:43:54 +0200520 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200521 ret = MBEDTLS_ERR_DHM_INVALID_FORMAT + ret;
Paul Bakker40ce79f2013-09-15 17:43:54 +0200522 goto exit;
523 }
524
525 end = p + len;
526
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200527 if( ( ret = mbedtls_asn1_get_mpi( &p, end, &dhm->P ) ) != 0 ||
528 ( ret = mbedtls_asn1_get_mpi( &p, end, &dhm->G ) ) != 0 )
Paul Bakker40ce79f2013-09-15 17:43:54 +0200529 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200530 ret = MBEDTLS_ERR_DHM_INVALID_FORMAT + ret;
Paul Bakker40ce79f2013-09-15 17:43:54 +0200531 goto exit;
532 }
533
534 if( p != end )
535 {
Manuel Pégourié-Gonnardde9b3632015-04-17 20:06:31 +0200536 /* This might be the optional privateValueLength.
537 * If so, we can cleanly discard it */
538 mbedtls_mpi rec;
539 mbedtls_mpi_init( &rec );
540 ret = mbedtls_asn1_get_mpi( &p, end, &rec );
541 mbedtls_mpi_free( &rec );
Daniel Kahn Gillmor2ed81732015-04-03 13:09:24 -0400542 if ( ret != 0 )
543 {
Manuel Pégourié-Gonnardde9b3632015-04-17 20:06:31 +0200544 ret = MBEDTLS_ERR_DHM_INVALID_FORMAT + ret;
Daniel Kahn Gillmor2ed81732015-04-03 13:09:24 -0400545 goto exit;
546 }
547 if ( p != end )
548 {
Manuel Pégourié-Gonnardde9b3632015-04-17 20:06:31 +0200549 ret = MBEDTLS_ERR_DHM_INVALID_FORMAT +
550 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH;
Daniel Kahn Gillmor2ed81732015-04-03 13:09:24 -0400551 goto exit;
552 }
Paul Bakker40ce79f2013-09-15 17:43:54 +0200553 }
554
555 ret = 0;
556
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200557 dhm->len = mbedtls_mpi_size( &dhm->P );
Manuel Pégourié-Gonnard3fec2202014-03-29 16:42:38 +0100558
Paul Bakker40ce79f2013-09-15 17:43:54 +0200559exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200560#if defined(MBEDTLS_PEM_PARSE_C)
561 mbedtls_pem_free( &pem );
Paul Bakker40ce79f2013-09-15 17:43:54 +0200562#endif
563 if( ret != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200564 mbedtls_dhm_free( dhm );
Paul Bakker40ce79f2013-09-15 17:43:54 +0200565
566 return( ret );
567}
568
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200569#if defined(MBEDTLS_FS_IO)
Paul Bakker40ce79f2013-09-15 17:43:54 +0200570/*
571 * Load all data from a file into a given buffer.
Manuel Pégourié-Gonnard43b37cb2015-05-12 11:20:10 +0200572 *
573 * The file is expected to contain either PEM or DER encoded data.
574 * A terminating null byte is always appended. It is included in the announced
575 * length only if the data looks like it is PEM encoded.
Paul Bakker40ce79f2013-09-15 17:43:54 +0200576 */
577static int load_file( const char *path, unsigned char **buf, size_t *n )
578{
579 FILE *f;
580 long size;
581
582 if( ( f = fopen( path, "rb" ) ) == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200583 return( MBEDTLS_ERR_DHM_FILE_IO_ERROR );
Paul Bakker40ce79f2013-09-15 17:43:54 +0200584
585 fseek( f, 0, SEEK_END );
586 if( ( size = ftell( f ) ) == -1 )
587 {
588 fclose( f );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200589 return( MBEDTLS_ERR_DHM_FILE_IO_ERROR );
Paul Bakker40ce79f2013-09-15 17:43:54 +0200590 }
591 fseek( f, 0, SEEK_SET );
592
593 *n = (size_t) size;
594
595 if( *n + 1 == 0 ||
Manuel Pégourié-Gonnard7551cb92015-05-26 16:04:06 +0200596 ( *buf = mbedtls_calloc( 1, *n + 1 ) ) == NULL )
Paul Bakker40ce79f2013-09-15 17:43:54 +0200597 {
598 fclose( f );
Manuel Pégourié-Gonnard6a8ca332015-05-28 09:33:39 +0200599 return( MBEDTLS_ERR_DHM_ALLOC_FAILED );
Paul Bakker40ce79f2013-09-15 17:43:54 +0200600 }
601
602 if( fread( *buf, 1, *n, f ) != *n )
603 {
604 fclose( f );
Andres Amaya Garciabdbca7b2017-06-23 16:23:21 +0100605
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500606 mbedtls_platform_zeroize( *buf, *n + 1 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200607 mbedtls_free( *buf );
Andres Amaya Garciabdbca7b2017-06-23 16:23:21 +0100608
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200609 return( MBEDTLS_ERR_DHM_FILE_IO_ERROR );
Paul Bakker40ce79f2013-09-15 17:43:54 +0200610 }
611
612 fclose( f );
613
614 (*buf)[*n] = '\0';
615
Manuel Pégourié-Gonnard43b37cb2015-05-12 11:20:10 +0200616 if( strstr( (const char *) *buf, "-----BEGIN " ) != NULL )
617 ++*n;
618
Paul Bakker40ce79f2013-09-15 17:43:54 +0200619 return( 0 );
620}
621
622/*
623 * Load and parse DHM parameters
624 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200625int mbedtls_dhm_parse_dhmfile( mbedtls_dhm_context *dhm, const char *path )
Paul Bakker40ce79f2013-09-15 17:43:54 +0200626{
Janos Follath24eed8d2019-11-22 13:21:35 +0000627 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker40ce79f2013-09-15 17:43:54 +0200628 size_t n;
629 unsigned char *buf;
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500630 DHM_VALIDATE_RET( dhm != NULL );
631 DHM_VALIDATE_RET( path != NULL );
Paul Bakker40ce79f2013-09-15 17:43:54 +0200632
Paul Bakker66d5d072014-06-17 16:39:18 +0200633 if( ( ret = load_file( path, &buf, &n ) ) != 0 )
Paul Bakker40ce79f2013-09-15 17:43:54 +0200634 return( ret );
635
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200636 ret = mbedtls_dhm_parse_dhm( dhm, buf, n );
Paul Bakker40ce79f2013-09-15 17:43:54 +0200637
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500638 mbedtls_platform_zeroize( buf, n );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200639 mbedtls_free( buf );
Paul Bakker40ce79f2013-09-15 17:43:54 +0200640
641 return( ret );
642}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200643#endif /* MBEDTLS_FS_IO */
644#endif /* MBEDTLS_ASN1_PARSE_C */
nirekh0149762fa2017-12-25 06:46:48 +0000645#endif /* MBEDTLS_DHM_ALT */
Paul Bakker40ce79f2013-09-15 17:43:54 +0200646
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200647#if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +0000648
Hanno Becker8b0f9e62019-05-31 17:28:59 +0100649#if defined(MBEDTLS_PEM_PARSE_C)
Manuel Pégourié-Gonnard53585ee2015-06-25 08:52:25 +0200650static const char mbedtls_test_dhm_params[] =
651"-----BEGIN DH PARAMETERS-----\r\n"
652"MIGHAoGBAJ419DBEOgmQTzo5qXl5fQcN9TN455wkOL7052HzxxRVMyhYmwQcgJvh\r\n"
653"1sa18fyfR9OiVEMYglOpkqVoGLN7qd5aQNNi5W7/C+VBdHTBJcGZJyyP5B3qcz32\r\n"
654"9mLJKudlVudV0Qxk5qUJaPZ/xupz0NyoVpviuiBOI1gNi8ovSXWzAgEC\r\n"
655"-----END DH PARAMETERS-----\r\n";
Hanno Becker8b0f9e62019-05-31 17:28:59 +0100656#else /* MBEDTLS_PEM_PARSE_C */
657static const char mbedtls_test_dhm_params[] = {
658 0x30, 0x81, 0x87, 0x02, 0x81, 0x81, 0x00, 0x9e, 0x35, 0xf4, 0x30, 0x44,
659 0x3a, 0x09, 0x90, 0x4f, 0x3a, 0x39, 0xa9, 0x79, 0x79, 0x7d, 0x07, 0x0d,
660 0xf5, 0x33, 0x78, 0xe7, 0x9c, 0x24, 0x38, 0xbe, 0xf4, 0xe7, 0x61, 0xf3,
661 0xc7, 0x14, 0x55, 0x33, 0x28, 0x58, 0x9b, 0x04, 0x1c, 0x80, 0x9b, 0xe1,
662 0xd6, 0xc6, 0xb5, 0xf1, 0xfc, 0x9f, 0x47, 0xd3, 0xa2, 0x54, 0x43, 0x18,
663 0x82, 0x53, 0xa9, 0x92, 0xa5, 0x68, 0x18, 0xb3, 0x7b, 0xa9, 0xde, 0x5a,
664 0x40, 0xd3, 0x62, 0xe5, 0x6e, 0xff, 0x0b, 0xe5, 0x41, 0x74, 0x74, 0xc1,
665 0x25, 0xc1, 0x99, 0x27, 0x2c, 0x8f, 0xe4, 0x1d, 0xea, 0x73, 0x3d, 0xf6,
666 0xf6, 0x62, 0xc9, 0x2a, 0xe7, 0x65, 0x56, 0xe7, 0x55, 0xd1, 0x0c, 0x64,
667 0xe6, 0xa5, 0x09, 0x68, 0xf6, 0x7f, 0xc6, 0xea, 0x73, 0xd0, 0xdc, 0xa8,
668 0x56, 0x9b, 0xe2, 0xba, 0x20, 0x4e, 0x23, 0x58, 0x0d, 0x8b, 0xca, 0x2f,
669 0x49, 0x75, 0xb3, 0x02, 0x01, 0x02 };
670#endif /* MBEDTLS_PEM_PARSE_C */
Manuel Pégourié-Gonnard53585ee2015-06-25 08:52:25 +0200671
672static const size_t mbedtls_test_dhm_params_len = sizeof( mbedtls_test_dhm_params );
Paul Bakker40ce79f2013-09-15 17:43:54 +0200673
Paul Bakker5121ce52009-01-03 21:22:43 +0000674/*
675 * Checkup routine
676 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200677int mbedtls_dhm_self_test( int verbose )
Paul Bakker5121ce52009-01-03 21:22:43 +0000678{
Janos Follath24eed8d2019-11-22 13:21:35 +0000679 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200680 mbedtls_dhm_context dhm;
Paul Bakker40ce79f2013-09-15 17:43:54 +0200681
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200682 mbedtls_dhm_init( &dhm );
Paul Bakker8f870b02014-06-20 13:32:38 +0200683
Paul Bakker40ce79f2013-09-15 17:43:54 +0200684 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200685 mbedtls_printf( " DHM parameter load: " );
Paul Bakker40ce79f2013-09-15 17:43:54 +0200686
Manuel Pégourié-Gonnard53585ee2015-06-25 08:52:25 +0200687 if( ( ret = mbedtls_dhm_parse_dhm( &dhm,
688 (const unsigned char *) mbedtls_test_dhm_params,
689 mbedtls_test_dhm_params_len ) ) != 0 )
Paul Bakker40ce79f2013-09-15 17:43:54 +0200690 {
691 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200692 mbedtls_printf( "failed\n" );
Paul Bakker40ce79f2013-09-15 17:43:54 +0200693
Manuel Pégourié-Gonnardb196fc22014-07-09 16:53:29 +0200694 ret = 1;
Paul Bakker8f870b02014-06-20 13:32:38 +0200695 goto exit;
Paul Bakker40ce79f2013-09-15 17:43:54 +0200696 }
697
698 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200699 mbedtls_printf( "passed\n\n" );
Paul Bakker40ce79f2013-09-15 17:43:54 +0200700
Paul Bakker8f870b02014-06-20 13:32:38 +0200701exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200702 mbedtls_dhm_free( &dhm );
Paul Bakker40ce79f2013-09-15 17:43:54 +0200703
Paul Bakker8f870b02014-06-20 13:32:38 +0200704 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000705}
706
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200707#endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +0000708
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200709#endif /* MBEDTLS_DHM_C */