blob: 1ba533907419b4d48bc1a25eff1270e3e3fb61a2 [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
Paul Bakker5121ce52009-01-03 21:22:43 +000058/*
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020059 * helper to validate the mbedtls_mpi size and import it
Paul Bakker5121ce52009-01-03 21:22:43 +000060 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020061static int dhm_read_bignum( mbedtls_mpi *X,
Paul Bakker5121ce52009-01-03 21:22:43 +000062 unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +000063 const unsigned char *end )
Paul Bakker5121ce52009-01-03 21:22:43 +000064{
65 int ret, n;
66
67 if( end - *p < 2 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020068 return( MBEDTLS_ERR_DHM_BAD_INPUT_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +000069
70 n = ( (*p)[0] << 8 ) | (*p)[1];
71 (*p) += 2;
72
73 if( (int)( end - *p ) < n )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020074 return( MBEDTLS_ERR_DHM_BAD_INPUT_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +000075
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020076 if( ( ret = mbedtls_mpi_read_binary( X, *p, n ) ) != 0 )
Chris Jones9f7a6932021-04-14 12:12:09 +010077 return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_DHM_READ_PARAMS_FAILED, ret ) );
Paul Bakker5121ce52009-01-03 21:22:43 +000078
79 (*p) += n;
80
81 return( 0 );
82}
83
84/*
Paul Bakkeraec37cb2012-04-26 18:59:59 +000085 * Verify sanity of parameter with regards to P
Paul Bakker345a6fe2011-02-28 21:20:02 +000086 *
Paul Bakkeraec37cb2012-04-26 18:59:59 +000087 * Parameter should be: 2 <= public_param <= P - 2
Paul Bakker345a6fe2011-02-28 21:20:02 +000088 *
Janos Follathaa325d72017-09-20 15:33:24 +010089 * This means that we need to return an error if
Janos Follath1ad1c6d2017-09-21 09:02:11 +010090 * public_param < 2 or public_param > P-2
Janos Follathaa325d72017-09-20 15:33:24 +010091 *
Paul Bakker345a6fe2011-02-28 21:20:02 +000092 * For more information on the attack, see:
93 * http://www.cl.cam.ac.uk/~rja14/Papers/psandqs.pdf
94 * http://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2005-2643
Paul Bakkerc47840e2011-02-20 16:37:30 +000095 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020096static int dhm_check_range( const mbedtls_mpi *param, const mbedtls_mpi *P )
Paul Bakkerc47840e2011-02-20 16:37:30 +000097{
Gilles Peskine8e38acc2021-03-31 22:56:43 +020098 mbedtls_mpi U;
Janos Follathaa325d72017-09-20 15:33:24 +010099 int ret = 0;
Paul Bakkerc47840e2011-02-20 16:37:30 +0000100
Gilles Peskine8e38acc2021-03-31 22:56:43 +0200101 mbedtls_mpi_init( &U );
Paul Bakker3d8fb632014-04-17 12:42:41 +0200102
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200103 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &U, P, 2 ) );
Paul Bakkerc47840e2011-02-20 16:37:30 +0000104
Gilles Peskine8e38acc2021-03-31 22:56:43 +0200105 if( mbedtls_mpi_cmp_int( param, 2 ) < 0 ||
Janos Follathaa325d72017-09-20 15:33:24 +0100106 mbedtls_mpi_cmp_mpi( param, &U ) > 0 )
Paul Bakkerc47840e2011-02-20 16:37:30 +0000107 {
Janos Follathaa325d72017-09-20 15:33:24 +0100108 ret = MBEDTLS_ERR_DHM_BAD_INPUT_DATA;
Paul Bakkerc47840e2011-02-20 16:37:30 +0000109 }
110
Paul Bakker3d8fb632014-04-17 12:42:41 +0200111cleanup:
Gilles Peskine8e38acc2021-03-31 22:56:43 +0200112 mbedtls_mpi_free( &U );
Paul Bakker345a6fe2011-02-28 21:20:02 +0000113 return( ret );
Paul Bakkerc47840e2011-02-20 16:37:30 +0000114}
115
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200116void mbedtls_dhm_init( mbedtls_dhm_context *ctx )
Paul Bakker8f870b02014-06-20 13:32:38 +0200117{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200118 memset( ctx, 0, sizeof( mbedtls_dhm_context ) );
Paul Bakker8f870b02014-06-20 13:32:38 +0200119}
120
Gilles Peskine487bbf62021-05-27 22:17:07 +0200121size_t mbedtls_dhm_get_bitlen( const mbedtls_dhm_context *ctx )
122{
123 return( mbedtls_mpi_bitlen( &ctx->P ) );
124}
125
126size_t mbedtls_dhm_get_len( const mbedtls_dhm_context *ctx )
127{
128 return( mbedtls_mpi_size( &ctx->P ) );
129}
130
Gilles Peskinee5702482021-06-11 21:59:08 +0200131int mbedtls_dhm_get_value( const mbedtls_dhm_context *ctx,
132 mbedtls_dhm_parameter param,
133 mbedtls_mpi *dest )
Gilles Peskine71acc6e2021-05-27 22:50:53 +0200134{
135 const mbedtls_mpi *src = NULL;
136 switch( param )
137 {
138 case MBEDTLS_DHM_PARAM_P:
139 src = &ctx->P;
140 break;
141 case MBEDTLS_DHM_PARAM_G:
142 src = &ctx->G;
143 break;
144 case MBEDTLS_DHM_PARAM_X:
145 src = &ctx->X;
146 break;
147 case MBEDTLS_DHM_PARAM_GX:
148 src = &ctx->GX;
149 break;
150 case MBEDTLS_DHM_PARAM_GY:
151 src = &ctx->GY;
152 break;
153 case MBEDTLS_DHM_PARAM_K:
154 src = &ctx->K;
155 break;
156 default:
157 return( MBEDTLS_ERR_DHM_BAD_INPUT_DATA );
158 }
159 return( mbedtls_mpi_copy( dest, src ) );
160}
161
Paul Bakkerc47840e2011-02-20 16:37:30 +0000162/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000163 * Parse the ServerKeyExchange parameters
164 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200165int mbedtls_dhm_read_params( mbedtls_dhm_context *ctx,
Paul Bakker5121ce52009-01-03 21:22:43 +0000166 unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +0000167 const unsigned char *end )
Paul Bakker5121ce52009-01-03 21:22:43 +0000168{
Janos Follath24eed8d2019-11-22 13:21:35 +0000169 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker5121ce52009-01-03 21:22:43 +0000170
Paul Bakker5121ce52009-01-03 21:22:43 +0000171 if( ( ret = dhm_read_bignum( &ctx->P, p, end ) ) != 0 ||
172 ( ret = dhm_read_bignum( &ctx->G, p, end ) ) != 0 ||
173 ( ret = dhm_read_bignum( &ctx->GY, p, end ) ) != 0 )
174 return( ret );
175
Paul Bakker345a6fe2011-02-28 21:20:02 +0000176 if( ( ret = dhm_check_range( &ctx->GY, &ctx->P ) ) != 0 )
177 return( ret );
178
Paul Bakker5121ce52009-01-03 21:22:43 +0000179 return( 0 );
180}
181
Gilles Peskine17f1a262021-03-31 22:48:14 +0200182/*
Gilles Peskineda7ee012021-03-31 23:04:50 +0200183 * Pick a random R in the range [2, M-2] for blinding or key generation.
Gilles Peskine17f1a262021-03-31 22:48:14 +0200184 */
185static int dhm_random_below( mbedtls_mpi *R, const mbedtls_mpi *M,
186 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
187{
Gilles Peskineda7ee012021-03-31 23:04:50 +0200188 int ret;
Gilles Peskine17f1a262021-03-31 22:48:14 +0200189
Gilles Peskineda7ee012021-03-31 23:04:50 +0200190 MBEDTLS_MPI_CHK( mbedtls_mpi_random( R, 3, M, f_rng, p_rng ) );
191 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( R, R, 1 ) );
Gilles Peskine17f1a262021-03-31 22:48:14 +0200192
193cleanup:
194 return( ret );
195}
196
Gilles Peskinecb660f22021-03-31 22:35:13 +0200197static int dhm_make_common( mbedtls_dhm_context *ctx, int x_size,
198 int (*f_rng)(void *, unsigned char *, size_t),
199 void *p_rng )
Paul Bakker5121ce52009-01-03 21:22:43 +0000200{
Gilles Peskine17f1a262021-03-31 22:48:14 +0200201 int ret = 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000202
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200203 if( mbedtls_mpi_cmp_int( &ctx->P, 0 ) == 0 )
204 return( MBEDTLS_ERR_DHM_BAD_INPUT_DATA );
Gilles Peskine17f1a262021-03-31 22:48:14 +0200205 if( x_size < 0 )
206 return( MBEDTLS_ERR_DHM_BAD_INPUT_DATA );
Paul Bakkerb5b20f12012-09-16 15:07:49 +0000207
Gilles Peskine17f1a262021-03-31 22:48:14 +0200208 if( (unsigned) x_size < mbedtls_mpi_size( &ctx->P ) )
Paul Bakkeraec37cb2012-04-26 18:59:59 +0000209 {
Ron Eldor7269fee2017-01-12 14:50:50 +0200210 MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( &ctx->X, x_size, f_rng, p_rng ) );
Paul Bakkeraec37cb2012-04-26 18:59:59 +0000211 }
Gilles Peskine17f1a262021-03-31 22:48:14 +0200212 else
213 {
214 /* Generate X as large as possible ( <= P - 2 ) */
215 ret = dhm_random_below( &ctx->X, &ctx->P, f_rng, p_rng );
216 if( ret == MBEDTLS_ERR_MPI_NOT_ACCEPTABLE )
217 return( MBEDTLS_ERR_DHM_MAKE_PARAMS_FAILED );
218 if( ret != 0 )
219 return( ret );
220 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000221
Paul Bakkerff7fe672010-07-18 09:45:05 +0000222 /*
223 * Calculate GX = G^X mod P
224 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200225 MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &ctx->GX, &ctx->G, &ctx->X,
Paul Bakker5121ce52009-01-03 21:22:43 +0000226 &ctx->P , &ctx->RP ) );
227
Paul Bakker345a6fe2011-02-28 21:20:02 +0000228 if( ( ret = dhm_check_range( &ctx->GX, &ctx->P ) ) != 0 )
Paul Bakkerc47840e2011-02-20 16:37:30 +0000229 return( ret );
230
Gilles Peskinecb660f22021-03-31 22:35:13 +0200231cleanup:
232 return( ret );
233}
234
235/*
236 * Setup and write the ServerKeyExchange parameters
237 */
238int mbedtls_dhm_make_params( mbedtls_dhm_context *ctx, int x_size,
239 unsigned char *output, size_t *olen,
240 int (*f_rng)(void *, unsigned char *, size_t),
241 void *p_rng )
242{
243 int ret;
244 size_t n1, n2, n3;
245 unsigned char *p;
Gilles Peskinecb660f22021-03-31 22:35:13 +0200246
247 ret = dhm_make_common( ctx, x_size, f_rng, p_rng );
248 if( ret != 0 )
249 goto cleanup;
250
Paul Bakker5121ce52009-01-03 21:22:43 +0000251 /*
Gilles Peskine03299dc2021-04-13 22:10:24 +0200252 * Export P, G, GX. RFC 5246 §4.4 states that "leading zero octets are
253 * not required". We omit leading zeros for compactness.
Paul Bakker5121ce52009-01-03 21:22:43 +0000254 */
Hanno Beckerde6c1642017-10-02 15:03:15 +0100255#define DHM_MPI_EXPORT( X, n ) \
Hanno Beckere71ad122017-09-28 10:32:25 +0100256 do { \
Hanno Beckerde6c1642017-10-02 15:03:15 +0100257 MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( ( X ), \
258 p + 2, \
259 ( n ) ) ); \
Joe Subbianifbeb6922021-07-16 14:27:50 +0100260 *p++ = MBEDTLS_BYTE_1( n ); \
261 *p++ = MBEDTLS_BYTE_0( n ); \
Hanno Beckerde6c1642017-10-02 15:03:15 +0100262 p += ( n ); \
Hanno Beckere71ad122017-09-28 10:32:25 +0100263 } while( 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000264
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200265 n1 = mbedtls_mpi_size( &ctx->P );
266 n2 = mbedtls_mpi_size( &ctx->G );
267 n3 = mbedtls_mpi_size( &ctx->GX );
Paul Bakker5121ce52009-01-03 21:22:43 +0000268
269 p = output;
270 DHM_MPI_EXPORT( &ctx->P , n1 );
271 DHM_MPI_EXPORT( &ctx->G , n2 );
272 DHM_MPI_EXPORT( &ctx->GX, n3 );
273
Hanno Beckere71ad122017-09-28 10:32:25 +0100274 *olen = p - output;
Paul Bakker5121ce52009-01-03 21:22:43 +0000275
Paul Bakker5121ce52009-01-03 21:22:43 +0000276cleanup:
Gilles Peskinecb660f22021-03-31 22:35:13 +0200277 if( ret != 0 && ret > -128 )
278 ret = MBEDTLS_ERROR_ADD( MBEDTLS_ERR_DHM_MAKE_PARAMS_FAILED, ret );
279 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000280}
281
282/*
Hanno Becker8880e752017-10-04 13:15:08 +0100283 * Set prime modulus and generator
284 */
285int mbedtls_dhm_set_group( mbedtls_dhm_context *ctx,
286 const mbedtls_mpi *P,
287 const mbedtls_mpi *G )
288{
Janos Follath24eed8d2019-11-22 13:21:35 +0000289 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Hanno Becker8880e752017-10-04 13:15:08 +0100290
291 if( ( ret = mbedtls_mpi_copy( &ctx->P, P ) ) != 0 ||
292 ( ret = mbedtls_mpi_copy( &ctx->G, G ) ) != 0 )
293 {
Chris Jones9f7a6932021-04-14 12:12:09 +0100294 return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_DHM_SET_GROUP_FAILED, ret ) );
Hanno Becker8880e752017-10-04 13:15:08 +0100295 }
296
Hanno Becker8880e752017-10-04 13:15:08 +0100297 return( 0 );
298}
299
300/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000301 * Import the peer's public value G^Y
302 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200303int mbedtls_dhm_read_public( mbedtls_dhm_context *ctx,
Paul Bakker23986e52011-04-24 08:57:21 +0000304 const unsigned char *input, size_t ilen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000305{
Janos Follath24eed8d2019-11-22 13:21:35 +0000306 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker5121ce52009-01-03 21:22:43 +0000307
Gilles Peskine487bbf62021-05-27 22:17:07 +0200308 if( ilen < 1 || ilen > mbedtls_dhm_get_len( ctx ) )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200309 return( MBEDTLS_ERR_DHM_BAD_INPUT_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +0000310
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200311 if( ( ret = mbedtls_mpi_read_binary( &ctx->GY, input, ilen ) ) != 0 )
Chris Jones9f7a6932021-04-14 12:12:09 +0100312 return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_DHM_READ_PUBLIC_FAILED, ret ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000313
314 return( 0 );
315}
316
317/*
318 * Create own private value X and export G^X
319 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200320int mbedtls_dhm_make_public( mbedtls_dhm_context *ctx, int x_size,
Paul Bakker23986e52011-04-24 08:57:21 +0000321 unsigned char *output, size_t olen,
Paul Bakkera3d195c2011-11-27 21:07:34 +0000322 int (*f_rng)(void *, unsigned char *, size_t),
323 void *p_rng )
Paul Bakker5121ce52009-01-03 21:22:43 +0000324{
Gilles Peskinecb660f22021-03-31 22:35:13 +0200325 int ret;
Paul Bakker5121ce52009-01-03 21:22:43 +0000326
Gilles Peskine487bbf62021-05-27 22:17:07 +0200327 if( olen < 1 || olen > mbedtls_dhm_get_len( ctx ) )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200328 return( MBEDTLS_ERR_DHM_BAD_INPUT_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +0000329
Gilles Peskinecb660f22021-03-31 22:35:13 +0200330 ret = dhm_make_common( ctx, x_size, f_rng, p_rng );
331 if( ret == MBEDTLS_ERR_DHM_MAKE_PARAMS_FAILED )
332 return( MBEDTLS_ERR_DHM_MAKE_PUBLIC_FAILED );
333 if( ret != 0 )
334 goto cleanup;
Paul Bakkerc47840e2011-02-20 16:37:30 +0000335
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200336 MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &ctx->GX, output, olen ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000337
338cleanup:
Gilles Peskinecb660f22021-03-31 22:35:13 +0200339 if( ret != 0 && ret > -128 )
340 ret = MBEDTLS_ERROR_ADD( MBEDTLS_ERR_DHM_MAKE_PUBLIC_FAILED, ret );
341 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000342}
343
Manuel Pégourié-Gonnard9f58c4b2020-06-25 12:34:58 +0200344
345/*
Manuel Pégourié-Gonnard143b5022013-09-04 16:29:59 +0200346 * Use the blinding method and optimisation suggested in section 10 of:
347 * KOCHER, Paul C. Timing attacks on implementations of Diffie-Hellman, RSA,
Manuel Pégourié-Gonnard998930a2015-04-03 13:48:06 +0200348 * DSS, and other systems. In : Advances in Cryptology-CRYPTO'96. Springer
Manuel Pégourié-Gonnard143b5022013-09-04 16:29:59 +0200349 * Berlin Heidelberg, 1996. p. 104-113.
350 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200351static int dhm_update_blinding( mbedtls_dhm_context *ctx,
Manuel Pégourié-Gonnard143b5022013-09-04 16:29:59 +0200352 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
353{
Manuel Pégourié-Gonnard9f58c4b2020-06-25 12:34:58 +0200354 int ret;
Manuel Pégourié-Gonnardaf721672020-06-25 12:47:22 +0200355 mbedtls_mpi R;
356
357 mbedtls_mpi_init( &R );
Manuel Pégourié-Gonnard143b5022013-09-04 16:29:59 +0200358
359 /*
Manuel Pégourié-Gonnard15d5de12013-09-17 11:34:11 +0200360 * Don't use any blinding the first time a particular X is used,
361 * but remember it to use blinding next time.
Manuel Pégourié-Gonnard143b5022013-09-04 16:29:59 +0200362 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200363 if( mbedtls_mpi_cmp_mpi( &ctx->X, &ctx->pX ) != 0 )
Manuel Pégourié-Gonnarded8a02b2013-09-04 16:39:03 +0200364 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200365 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &ctx->pX, &ctx->X ) );
366 MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &ctx->Vi, 1 ) );
367 MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &ctx->Vf, 1 ) );
Manuel Pégourié-Gonnarded8a02b2013-09-04 16:39:03 +0200368
Manuel Pégourié-Gonnard143b5022013-09-04 16:29:59 +0200369 return( 0 );
370 }
371
372 /*
Manuel Pégourié-Gonnard15d5de12013-09-17 11:34:11 +0200373 * Ok, we need blinding. Can we re-use existing values?
374 * If yes, just update them by squaring them.
Manuel Pégourié-Gonnard143b5022013-09-04 16:29:59 +0200375 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200376 if( mbedtls_mpi_cmp_int( &ctx->Vi, 1 ) != 0 )
Manuel Pégourié-Gonnard15d5de12013-09-17 11:34:11 +0200377 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200378 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &ctx->Vi, &ctx->Vi, &ctx->Vi ) );
379 MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &ctx->Vi, &ctx->Vi, &ctx->P ) );
Manuel Pégourié-Gonnard15d5de12013-09-17 11:34:11 +0200380
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200381 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &ctx->Vf, &ctx->Vf, &ctx->Vf ) );
382 MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &ctx->Vf, &ctx->Vf, &ctx->P ) );
Manuel Pégourié-Gonnard15d5de12013-09-17 11:34:11 +0200383
384 return( 0 );
385 }
386
387 /*
388 * We need to generate blinding values from scratch
389 */
390
Gilles Peskine7b2b66e2021-03-31 22:50:57 +0200391 /* Vi = random( 2, P-2 ) */
Manuel Pégourié-Gonnard9f58c4b2020-06-25 12:34:58 +0200392 MBEDTLS_MPI_CHK( dhm_random_below( &ctx->Vi, &ctx->P, f_rng, p_rng ) );
Manuel Pégourié-Gonnard15d5de12013-09-17 11:34:11 +0200393
Manuel Pégourié-Gonnardaf721672020-06-25 12:47:22 +0200394 /* Vf = Vi^-X mod P
395 * First compute Vi^-1 = R * (R Vi)^-1, (avoiding leaks from inv_mod),
396 * then elevate to the Xth power. */
397 MBEDTLS_MPI_CHK( dhm_random_below( &R, &ctx->P, f_rng, p_rng ) );
398 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &ctx->Vf, &ctx->Vi, &R ) );
399 MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &ctx->Vf, &ctx->Vf, &ctx->P ) );
400 MBEDTLS_MPI_CHK( mbedtls_mpi_inv_mod( &ctx->Vf, &ctx->Vf, &ctx->P ) );
401 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &ctx->Vf, &ctx->Vf, &R ) );
402 MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &ctx->Vf, &ctx->Vf, &ctx->P ) );
Manuel Pégourié-Gonnard15d5de12013-09-17 11:34:11 +0200403
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200404 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 +0200405
Manuel Pégourié-Gonnard143b5022013-09-04 16:29:59 +0200406cleanup:
Manuel Pégourié-Gonnardaf721672020-06-25 12:47:22 +0200407 mbedtls_mpi_free( &R );
408
Manuel Pégourié-Gonnard143b5022013-09-04 16:29:59 +0200409 return( ret );
410}
411
412/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000413 * Derive and export the shared secret (G^Y)^X mod P
414 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200415int mbedtls_dhm_calc_secret( mbedtls_dhm_context *ctx,
Manuel Pégourié-Gonnard33352052015-06-02 16:17:08 +0100416 unsigned char *output, size_t output_size, size_t *olen,
Manuel Pégourié-Gonnard2d627642013-09-04 14:22:07 +0200417 int (*f_rng)(void *, unsigned char *, size_t),
418 void *p_rng )
Paul Bakker5121ce52009-01-03 21:22:43 +0000419{
Janos Follath24eed8d2019-11-22 13:21:35 +0000420 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200421 mbedtls_mpi GYb;
Manuel Pégourié-Gonnard2d627642013-09-04 14:22:07 +0200422
Manuel Pégourié-Gonnard1a877222021-06-15 11:29:26 +0200423 if( f_rng == NULL )
424 return( MBEDTLS_ERR_DHM_BAD_INPUT_DATA );
425
Gilles Peskine487bbf62021-05-27 22:17:07 +0200426 if( output_size < mbedtls_dhm_get_len( ctx ) )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200427 return( MBEDTLS_ERR_DHM_BAD_INPUT_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +0000428
Paul Bakker345a6fe2011-02-28 21:20:02 +0000429 if( ( ret = dhm_check_range( &ctx->GY, &ctx->P ) ) != 0 )
Paul Bakkerc47840e2011-02-20 16:37:30 +0000430 return( ret );
431
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200432 mbedtls_mpi_init( &GYb );
Manuel Pégourié-Gonnard143b5022013-09-04 16:29:59 +0200433
434 /* Blind peer's value */
Manuel Pégourié-Gonnard1a877222021-06-15 11:29:26 +0200435 MBEDTLS_MPI_CHK( dhm_update_blinding( ctx, f_rng, p_rng ) );
436 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &GYb, &ctx->GY, &ctx->Vi ) );
437 MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &GYb, &GYb, &ctx->P ) );
Manuel Pégourié-Gonnard143b5022013-09-04 16:29:59 +0200438
439 /* Do modular exponentiation */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200440 MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &ctx->K, &GYb, &ctx->X,
Manuel Pégourié-Gonnard143b5022013-09-04 16:29:59 +0200441 &ctx->P, &ctx->RP ) );
442
443 /* Unblind secret value */
Manuel Pégourié-Gonnard1a877222021-06-15 11:29:26 +0200444 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &ctx->K, &ctx->K, &ctx->Vf ) );
445 MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &ctx->K, &ctx->K, &ctx->P ) );
Manuel Pégourié-Gonnard143b5022013-09-04 16:29:59 +0200446
Gilles Peskine03299dc2021-04-13 22:10:24 +0200447 /* Output the secret without any leading zero byte. This is mandatory
448 * for TLS per RFC 5246 §8.1.2. */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200449 *olen = mbedtls_mpi_size( &ctx->K );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200450 MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &ctx->K, output, *olen ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000451
452cleanup:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200453 mbedtls_mpi_free( &GYb );
Paul Bakker5121ce52009-01-03 21:22:43 +0000454
455 if( ret != 0 )
Chris Jones9f7a6932021-04-14 12:12:09 +0100456 return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_DHM_CALC_SECRET_FAILED, ret ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000457
458 return( 0 );
459}
460
461/*
462 * Free the components of a DHM key
463 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200464void mbedtls_dhm_free( mbedtls_dhm_context *ctx )
Paul Bakker5121ce52009-01-03 21:22:43 +0000465{
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500466 if( ctx == NULL )
467 return;
468
469 mbedtls_mpi_free( &ctx->pX );
470 mbedtls_mpi_free( &ctx->Vf );
471 mbedtls_mpi_free( &ctx->Vi );
472 mbedtls_mpi_free( &ctx->RP );
473 mbedtls_mpi_free( &ctx->K );
474 mbedtls_mpi_free( &ctx->GY );
475 mbedtls_mpi_free( &ctx->GX );
476 mbedtls_mpi_free( &ctx->X );
477 mbedtls_mpi_free( &ctx->G );
478 mbedtls_mpi_free( &ctx->P );
Manuel Pégourié-Gonnardb72b4ed2013-09-13 13:55:26 +0200479
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500480 mbedtls_platform_zeroize( ctx, sizeof( mbedtls_dhm_context ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000481}
482
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200483#if defined(MBEDTLS_ASN1_PARSE_C)
Paul Bakker40ce79f2013-09-15 17:43:54 +0200484/*
485 * Parse DHM parameters
486 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200487int mbedtls_dhm_parse_dhm( mbedtls_dhm_context *dhm, const unsigned char *dhmin,
Paul Bakkerb9e4e2c2014-05-01 14:18:25 +0200488 size_t dhminlen )
Paul Bakker40ce79f2013-09-15 17:43:54 +0200489{
Janos Follath24eed8d2019-11-22 13:21:35 +0000490 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker40ce79f2013-09-15 17:43:54 +0200491 size_t len;
492 unsigned char *p, *end;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200493#if defined(MBEDTLS_PEM_PARSE_C)
494 mbedtls_pem_context pem;
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500495#endif /* MBEDTLS_PEM_PARSE_C */
Paul Bakker40ce79f2013-09-15 17:43:54 +0200496
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500497#if defined(MBEDTLS_PEM_PARSE_C)
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200498 mbedtls_pem_init( &pem );
Paul Bakker40ce79f2013-09-15 17:43:54 +0200499
Manuel Pégourié-Gonnard43b37cb2015-05-12 11:20:10 +0200500 /* Avoid calling mbedtls_pem_read_buffer() on non-null-terminated string */
Manuel Pégourié-Gonnard0ece0f92015-05-12 12:43:54 +0200501 if( dhminlen == 0 || dhmin[dhminlen - 1] != '\0' )
Manuel Pégourié-Gonnard43b37cb2015-05-12 11:20:10 +0200502 ret = MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT;
503 else
504 ret = mbedtls_pem_read_buffer( &pem,
505 "-----BEGIN DH PARAMETERS-----",
506 "-----END DH PARAMETERS-----",
507 dhmin, NULL, 0, &dhminlen );
Paul Bakker40ce79f2013-09-15 17:43:54 +0200508
509 if( ret == 0 )
510 {
511 /*
512 * Was PEM encoded
513 */
514 dhminlen = pem.buflen;
515 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200516 else if( ret != MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
Paul Bakker40ce79f2013-09-15 17:43:54 +0200517 goto exit;
518
519 p = ( ret == 0 ) ? pem.buf : (unsigned char *) dhmin;
520#else
521 p = (unsigned char *) dhmin;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200522#endif /* MBEDTLS_PEM_PARSE_C */
Paul Bakker40ce79f2013-09-15 17:43:54 +0200523 end = p + dhminlen;
524
525 /*
526 * DHParams ::= SEQUENCE {
Daniel Kahn Gillmor2ed81732015-04-03 13:09:24 -0400527 * prime INTEGER, -- P
528 * generator INTEGER, -- g
529 * privateValueLength INTEGER OPTIONAL
Paul Bakker40ce79f2013-09-15 17:43:54 +0200530 * }
531 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200532 if( ( ret = mbedtls_asn1_get_tag( &p, end, &len,
533 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
Paul Bakker40ce79f2013-09-15 17:43:54 +0200534 {
Chris Jones9f7a6932021-04-14 12:12:09 +0100535 ret = MBEDTLS_ERROR_ADD( MBEDTLS_ERR_DHM_INVALID_FORMAT, ret );
Paul Bakker40ce79f2013-09-15 17:43:54 +0200536 goto exit;
537 }
538
539 end = p + len;
540
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200541 if( ( ret = mbedtls_asn1_get_mpi( &p, end, &dhm->P ) ) != 0 ||
542 ( ret = mbedtls_asn1_get_mpi( &p, end, &dhm->G ) ) != 0 )
Paul Bakker40ce79f2013-09-15 17:43:54 +0200543 {
Chris Jones9f7a6932021-04-14 12:12:09 +0100544 ret = MBEDTLS_ERROR_ADD( MBEDTLS_ERR_DHM_INVALID_FORMAT, ret );
Paul Bakker40ce79f2013-09-15 17:43:54 +0200545 goto exit;
546 }
547
548 if( p != end )
549 {
Manuel Pégourié-Gonnardde9b3632015-04-17 20:06:31 +0200550 /* This might be the optional privateValueLength.
551 * If so, we can cleanly discard it */
552 mbedtls_mpi rec;
553 mbedtls_mpi_init( &rec );
554 ret = mbedtls_asn1_get_mpi( &p, end, &rec );
555 mbedtls_mpi_free( &rec );
Daniel Kahn Gillmor2ed81732015-04-03 13:09:24 -0400556 if ( ret != 0 )
557 {
Chris Jones9f7a6932021-04-14 12:12:09 +0100558 ret = MBEDTLS_ERROR_ADD( MBEDTLS_ERR_DHM_INVALID_FORMAT, ret );
Daniel Kahn Gillmor2ed81732015-04-03 13:09:24 -0400559 goto exit;
560 }
561 if ( p != end )
562 {
Chris Jones9f7a6932021-04-14 12:12:09 +0100563 ret = MBEDTLS_ERROR_ADD( MBEDTLS_ERR_DHM_INVALID_FORMAT,
564 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
Daniel Kahn Gillmor2ed81732015-04-03 13:09:24 -0400565 goto exit;
566 }
Paul Bakker40ce79f2013-09-15 17:43:54 +0200567 }
568
569 ret = 0;
570
571exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200572#if defined(MBEDTLS_PEM_PARSE_C)
573 mbedtls_pem_free( &pem );
Paul Bakker40ce79f2013-09-15 17:43:54 +0200574#endif
575 if( ret != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200576 mbedtls_dhm_free( dhm );
Paul Bakker40ce79f2013-09-15 17:43:54 +0200577
578 return( ret );
579}
580
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200581#if defined(MBEDTLS_FS_IO)
Paul Bakker40ce79f2013-09-15 17:43:54 +0200582/*
583 * Load all data from a file into a given buffer.
Manuel Pégourié-Gonnard43b37cb2015-05-12 11:20:10 +0200584 *
585 * The file is expected to contain either PEM or DER encoded data.
586 * A terminating null byte is always appended. It is included in the announced
587 * length only if the data looks like it is PEM encoded.
Paul Bakker40ce79f2013-09-15 17:43:54 +0200588 */
589static int load_file( const char *path, unsigned char **buf, size_t *n )
590{
591 FILE *f;
592 long size;
593
594 if( ( f = fopen( path, "rb" ) ) == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200595 return( MBEDTLS_ERR_DHM_FILE_IO_ERROR );
Gilles Peskineda0913b2022-06-30 17:03:40 +0200596 /* The data loaded here is public, so don't bother disabling buffering. */
Paul Bakker40ce79f2013-09-15 17:43:54 +0200597
598 fseek( f, 0, SEEK_END );
599 if( ( size = ftell( f ) ) == -1 )
600 {
601 fclose( f );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200602 return( MBEDTLS_ERR_DHM_FILE_IO_ERROR );
Paul Bakker40ce79f2013-09-15 17:43:54 +0200603 }
604 fseek( f, 0, SEEK_SET );
605
606 *n = (size_t) size;
607
608 if( *n + 1 == 0 ||
Manuel Pégourié-Gonnard7551cb92015-05-26 16:04:06 +0200609 ( *buf = mbedtls_calloc( 1, *n + 1 ) ) == NULL )
Paul Bakker40ce79f2013-09-15 17:43:54 +0200610 {
611 fclose( f );
Manuel Pégourié-Gonnard6a8ca332015-05-28 09:33:39 +0200612 return( MBEDTLS_ERR_DHM_ALLOC_FAILED );
Paul Bakker40ce79f2013-09-15 17:43:54 +0200613 }
614
615 if( fread( *buf, 1, *n, f ) != *n )
616 {
617 fclose( f );
Andres Amaya Garciabdbca7b2017-06-23 16:23:21 +0100618
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500619 mbedtls_platform_zeroize( *buf, *n + 1 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200620 mbedtls_free( *buf );
Andres Amaya Garciabdbca7b2017-06-23 16:23:21 +0100621
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200622 return( MBEDTLS_ERR_DHM_FILE_IO_ERROR );
Paul Bakker40ce79f2013-09-15 17:43:54 +0200623 }
624
625 fclose( f );
626
627 (*buf)[*n] = '\0';
628
Manuel Pégourié-Gonnard43b37cb2015-05-12 11:20:10 +0200629 if( strstr( (const char *) *buf, "-----BEGIN " ) != NULL )
630 ++*n;
631
Paul Bakker40ce79f2013-09-15 17:43:54 +0200632 return( 0 );
633}
634
635/*
636 * Load and parse DHM parameters
637 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200638int mbedtls_dhm_parse_dhmfile( mbedtls_dhm_context *dhm, const char *path )
Paul Bakker40ce79f2013-09-15 17:43:54 +0200639{
Janos Follath24eed8d2019-11-22 13:21:35 +0000640 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker40ce79f2013-09-15 17:43:54 +0200641 size_t n;
642 unsigned char *buf;
643
Paul Bakker66d5d072014-06-17 16:39:18 +0200644 if( ( ret = load_file( path, &buf, &n ) ) != 0 )
Paul Bakker40ce79f2013-09-15 17:43:54 +0200645 return( ret );
646
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200647 ret = mbedtls_dhm_parse_dhm( dhm, buf, n );
Paul Bakker40ce79f2013-09-15 17:43:54 +0200648
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500649 mbedtls_platform_zeroize( buf, n );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200650 mbedtls_free( buf );
Paul Bakker40ce79f2013-09-15 17:43:54 +0200651
652 return( ret );
653}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200654#endif /* MBEDTLS_FS_IO */
655#endif /* MBEDTLS_ASN1_PARSE_C */
nirekh0149762fa2017-12-25 06:46:48 +0000656#endif /* MBEDTLS_DHM_ALT */
Paul Bakker40ce79f2013-09-15 17:43:54 +0200657
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200658#if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +0000659
Hanno Becker8b0f9e62019-05-31 17:28:59 +0100660#if defined(MBEDTLS_PEM_PARSE_C)
Manuel Pégourié-Gonnard53585ee2015-06-25 08:52:25 +0200661static const char mbedtls_test_dhm_params[] =
662"-----BEGIN DH PARAMETERS-----\r\n"
663"MIGHAoGBAJ419DBEOgmQTzo5qXl5fQcN9TN455wkOL7052HzxxRVMyhYmwQcgJvh\r\n"
664"1sa18fyfR9OiVEMYglOpkqVoGLN7qd5aQNNi5W7/C+VBdHTBJcGZJyyP5B3qcz32\r\n"
665"9mLJKudlVudV0Qxk5qUJaPZ/xupz0NyoVpviuiBOI1gNi8ovSXWzAgEC\r\n"
666"-----END DH PARAMETERS-----\r\n";
Hanno Becker8b0f9e62019-05-31 17:28:59 +0100667#else /* MBEDTLS_PEM_PARSE_C */
668static const char mbedtls_test_dhm_params[] = {
669 0x30, 0x81, 0x87, 0x02, 0x81, 0x81, 0x00, 0x9e, 0x35, 0xf4, 0x30, 0x44,
670 0x3a, 0x09, 0x90, 0x4f, 0x3a, 0x39, 0xa9, 0x79, 0x79, 0x7d, 0x07, 0x0d,
671 0xf5, 0x33, 0x78, 0xe7, 0x9c, 0x24, 0x38, 0xbe, 0xf4, 0xe7, 0x61, 0xf3,
672 0xc7, 0x14, 0x55, 0x33, 0x28, 0x58, 0x9b, 0x04, 0x1c, 0x80, 0x9b, 0xe1,
673 0xd6, 0xc6, 0xb5, 0xf1, 0xfc, 0x9f, 0x47, 0xd3, 0xa2, 0x54, 0x43, 0x18,
674 0x82, 0x53, 0xa9, 0x92, 0xa5, 0x68, 0x18, 0xb3, 0x7b, 0xa9, 0xde, 0x5a,
675 0x40, 0xd3, 0x62, 0xe5, 0x6e, 0xff, 0x0b, 0xe5, 0x41, 0x74, 0x74, 0xc1,
676 0x25, 0xc1, 0x99, 0x27, 0x2c, 0x8f, 0xe4, 0x1d, 0xea, 0x73, 0x3d, 0xf6,
677 0xf6, 0x62, 0xc9, 0x2a, 0xe7, 0x65, 0x56, 0xe7, 0x55, 0xd1, 0x0c, 0x64,
678 0xe6, 0xa5, 0x09, 0x68, 0xf6, 0x7f, 0xc6, 0xea, 0x73, 0xd0, 0xdc, 0xa8,
679 0x56, 0x9b, 0xe2, 0xba, 0x20, 0x4e, 0x23, 0x58, 0x0d, 0x8b, 0xca, 0x2f,
680 0x49, 0x75, 0xb3, 0x02, 0x01, 0x02 };
681#endif /* MBEDTLS_PEM_PARSE_C */
Manuel Pégourié-Gonnard53585ee2015-06-25 08:52:25 +0200682
683static const size_t mbedtls_test_dhm_params_len = sizeof( mbedtls_test_dhm_params );
Paul Bakker40ce79f2013-09-15 17:43:54 +0200684
Paul Bakker5121ce52009-01-03 21:22:43 +0000685/*
686 * Checkup routine
687 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200688int mbedtls_dhm_self_test( int verbose )
Paul Bakker5121ce52009-01-03 21:22:43 +0000689{
Janos Follath24eed8d2019-11-22 13:21:35 +0000690 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200691 mbedtls_dhm_context dhm;
Paul Bakker40ce79f2013-09-15 17:43:54 +0200692
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200693 mbedtls_dhm_init( &dhm );
Paul Bakker8f870b02014-06-20 13:32:38 +0200694
Paul Bakker40ce79f2013-09-15 17:43:54 +0200695 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200696 mbedtls_printf( " DHM parameter load: " );
Paul Bakker40ce79f2013-09-15 17:43:54 +0200697
Manuel Pégourié-Gonnard53585ee2015-06-25 08:52:25 +0200698 if( ( ret = mbedtls_dhm_parse_dhm( &dhm,
699 (const unsigned char *) mbedtls_test_dhm_params,
700 mbedtls_test_dhm_params_len ) ) != 0 )
Paul Bakker40ce79f2013-09-15 17:43:54 +0200701 {
702 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200703 mbedtls_printf( "failed\n" );
Paul Bakker40ce79f2013-09-15 17:43:54 +0200704
Manuel Pégourié-Gonnardb196fc22014-07-09 16:53:29 +0200705 ret = 1;
Paul Bakker8f870b02014-06-20 13:32:38 +0200706 goto exit;
Paul Bakker40ce79f2013-09-15 17:43:54 +0200707 }
708
709 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200710 mbedtls_printf( "passed\n\n" );
Paul Bakker40ce79f2013-09-15 17:43:54 +0200711
Paul Bakker8f870b02014-06-20 13:32:38 +0200712exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200713 mbedtls_dhm_free( &dhm );
Paul Bakker40ce79f2013-09-15 17:43:54 +0200714
Paul Bakker8f870b02014-06-20 13:32:38 +0200715 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000716}
717
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200718#endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +0000719
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200720#endif /* MBEDTLS_DHM_C */