blob: 28ac31003c923bf9f49597c14c02c2aa67a3104c [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
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020030#if !defined(MBEDTLS_CONFIG_FILE)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000031#include "mbedtls/config.h"
Manuel Pégourié-Gonnardcef4ad22014-04-29 12:39:06 +020032#else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020033#include MBEDTLS_CONFIG_FILE
Manuel Pégourié-Gonnardcef4ad22014-04-29 12:39:06 +020034#endif
Paul Bakker5121ce52009-01-03 21:22:43 +000035
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020036#if defined(MBEDTLS_DHM_C)
Paul Bakker5121ce52009-01-03 21:22:43 +000037
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000038#include "mbedtls/dhm.h"
Paul Bakker5121ce52009-01-03 21:22:43 +000039
Rich Evans00ab4702015-02-06 13:43:58 +000040#include <string.h>
41
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020042#if defined(MBEDTLS_PEM_PARSE_C)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000043#include "mbedtls/pem.h"
Paul Bakker40ce79f2013-09-15 17:43:54 +020044#endif
45
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020046#if defined(MBEDTLS_ASN1_PARSE_C)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000047#include "mbedtls/asn1.h"
Paul Bakker40ce79f2013-09-15 17:43:54 +020048#endif
49
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020050#if defined(MBEDTLS_PLATFORM_C)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000051#include "mbedtls/platform.h"
Paul Bakker40ce79f2013-09-15 17:43:54 +020052#else
53#include <stdlib.h>
Manuel Pégourié-Gonnard981732b2015-02-17 15:46:45 +000054#include <stdio.h>
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020055#define mbedtls_printf printf
Manuel Pégourié-Gonnard7551cb92015-05-26 16:04:06 +020056#define mbedtls_calloc calloc
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020057#define mbedtls_free free
Paul Bakker40ce79f2013-09-15 17:43:54 +020058#endif
59
Reuven Levin1f35ca92017-12-07 10:09:32 +000060#if !defined(MBEDTLS_DHM_ALT)
Paul Bakker34617722014-06-13 17:20:13 +020061/* Implementation that should never be optimized out by the compiler */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020062static void mbedtls_zeroize( void *v, size_t n ) {
Paul Bakker34617722014-06-13 17:20:13 +020063 volatile unsigned char *p = v; while( n-- ) *p++ = 0;
64}
65
Paul Bakker5121ce52009-01-03 21:22:43 +000066/*
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020067 * helper to validate the mbedtls_mpi size and import it
Paul Bakker5121ce52009-01-03 21:22:43 +000068 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020069static int dhm_read_bignum( mbedtls_mpi *X,
Paul Bakker5121ce52009-01-03 21:22:43 +000070 unsigned char **p,
Paul Bakkerff60ee62010-03-16 21:09:09 +000071 const unsigned char *end )
Paul Bakker5121ce52009-01-03 21:22:43 +000072{
73 int ret, n;
74
75 if( end - *p < 2 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020076 return( MBEDTLS_ERR_DHM_BAD_INPUT_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +000077
78 n = ( (*p)[0] << 8 ) | (*p)[1];
79 (*p) += 2;
80
81 if( (int)( end - *p ) < n )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020082 return( MBEDTLS_ERR_DHM_BAD_INPUT_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +000083
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020084 if( ( ret = mbedtls_mpi_read_binary( X, *p, n ) ) != 0 )
85 return( MBEDTLS_ERR_DHM_READ_PARAMS_FAILED + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +000086
87 (*p) += n;
88
89 return( 0 );
90}
91
92/*
Paul Bakkeraec37cb2012-04-26 18:59:59 +000093 * Verify sanity of parameter with regards to P
Paul Bakker345a6fe2011-02-28 21:20:02 +000094 *
Paul Bakkeraec37cb2012-04-26 18:59:59 +000095 * Parameter should be: 2 <= public_param <= P - 2
Paul Bakker345a6fe2011-02-28 21:20:02 +000096 *
Janos Follathaa325d72017-09-20 15:33:24 +010097 * This means that we need to return an error if
Janos Follath1ad1c6d2017-09-21 09:02:11 +010098 * public_param < 2 or public_param > P-2
Janos Follathaa325d72017-09-20 15:33:24 +010099 *
Paul Bakker345a6fe2011-02-28 21:20:02 +0000100 * For more information on the attack, see:
101 * http://www.cl.cam.ac.uk/~rja14/Papers/psandqs.pdf
102 * http://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2005-2643
Paul Bakkerc47840e2011-02-20 16:37:30 +0000103 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200104static int dhm_check_range( const mbedtls_mpi *param, const mbedtls_mpi *P )
Paul Bakkerc47840e2011-02-20 16:37:30 +0000105{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200106 mbedtls_mpi L, U;
Janos Follathaa325d72017-09-20 15:33:24 +0100107 int ret = 0;
Paul Bakkerc47840e2011-02-20 16:37:30 +0000108
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200109 mbedtls_mpi_init( &L ); mbedtls_mpi_init( &U );
Paul Bakker3d8fb632014-04-17 12:42:41 +0200110
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200111 MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &L, 2 ) );
112 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &U, P, 2 ) );
Paul Bakkerc47840e2011-02-20 16:37:30 +0000113
Janos Follathaa325d72017-09-20 15:33:24 +0100114 if( mbedtls_mpi_cmp_mpi( param, &L ) < 0 ||
115 mbedtls_mpi_cmp_mpi( param, &U ) > 0 )
Paul Bakkerc47840e2011-02-20 16:37:30 +0000116 {
Janos Follathaa325d72017-09-20 15:33:24 +0100117 ret = MBEDTLS_ERR_DHM_BAD_INPUT_DATA;
Paul Bakkerc47840e2011-02-20 16:37:30 +0000118 }
119
Paul Bakker3d8fb632014-04-17 12:42:41 +0200120cleanup:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200121 mbedtls_mpi_free( &L ); mbedtls_mpi_free( &U );
Paul Bakker345a6fe2011-02-28 21:20:02 +0000122 return( ret );
Paul Bakkerc47840e2011-02-20 16:37:30 +0000123}
124
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200125void mbedtls_dhm_init( mbedtls_dhm_context *ctx )
Paul Bakker8f870b02014-06-20 13:32:38 +0200126{
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{
Paul Bakker13ed9ab2012-04-16 09:43:49 +0000137 int ret;
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
152/*
153 * Setup and write the ServerKeyExchange parameters
154 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200155int mbedtls_dhm_make_params( mbedtls_dhm_context *ctx, int x_size,
Paul Bakker23986e52011-04-24 08:57:21 +0000156 unsigned char *output, size_t *olen,
Paul Bakkera3d195c2011-11-27 21:07:34 +0000157 int (*f_rng)(void *, unsigned char *, size_t),
158 void *p_rng )
Paul Bakker5121ce52009-01-03 21:22:43 +0000159{
Paul Bakkeraec37cb2012-04-26 18:59:59 +0000160 int ret, count = 0;
Paul Bakker23986e52011-04-24 08:57:21 +0000161 size_t n1, n2, n3;
Paul Bakker5121ce52009-01-03 21:22:43 +0000162 unsigned char *p;
163
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200164 if( mbedtls_mpi_cmp_int( &ctx->P, 0 ) == 0 )
165 return( MBEDTLS_ERR_DHM_BAD_INPUT_DATA );
Paul Bakkerb5b20f12012-09-16 15:07:49 +0000166
Paul Bakker5121ce52009-01-03 21:22:43 +0000167 /*
Paul Bakkerff7fe672010-07-18 09:45:05 +0000168 * Generate X as large as possible ( < P )
Paul Bakker5121ce52009-01-03 21:22:43 +0000169 */
Paul Bakkeraec37cb2012-04-26 18:59:59 +0000170 do
171 {
Ron Eldor7269fee2017-01-12 14:50:50 +0200172 MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( &ctx->X, x_size, f_rng, p_rng ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000173
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200174 while( mbedtls_mpi_cmp_mpi( &ctx->X, &ctx->P ) >= 0 )
175 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &ctx->X, 1 ) );
Paul Bakkeraec37cb2012-04-26 18:59:59 +0000176
177 if( count++ > 10 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200178 return( MBEDTLS_ERR_DHM_MAKE_PARAMS_FAILED );
Paul Bakkeraec37cb2012-04-26 18:59:59 +0000179 }
180 while( dhm_check_range( &ctx->X, &ctx->P ) != 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000181
Paul Bakkerff7fe672010-07-18 09:45:05 +0000182 /*
183 * Calculate GX = G^X mod P
184 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200185 MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &ctx->GX, &ctx->G, &ctx->X,
Paul Bakker5121ce52009-01-03 21:22:43 +0000186 &ctx->P , &ctx->RP ) );
187
Paul Bakker345a6fe2011-02-28 21:20:02 +0000188 if( ( ret = dhm_check_range( &ctx->GX, &ctx->P ) ) != 0 )
Paul Bakkerc47840e2011-02-20 16:37:30 +0000189 return( ret );
190
Paul Bakker5121ce52009-01-03 21:22:43 +0000191 /*
192 * export P, G, GX
193 */
Hanno Beckerde6c1642017-10-02 15:03:15 +0100194#define DHM_MPI_EXPORT( X, n ) \
Hanno Beckere71ad122017-09-28 10:32:25 +0100195 do { \
Hanno Beckerde6c1642017-10-02 15:03:15 +0100196 MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( ( X ), \
197 p + 2, \
198 ( n ) ) ); \
199 *p++ = (unsigned char)( ( n ) >> 8 ); \
200 *p++ = (unsigned char)( ( n ) ); \
201 p += ( n ); \
Hanno Beckere71ad122017-09-28 10:32:25 +0100202 } while( 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000203
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200204 n1 = mbedtls_mpi_size( &ctx->P );
205 n2 = mbedtls_mpi_size( &ctx->G );
206 n3 = mbedtls_mpi_size( &ctx->GX );
Paul Bakker5121ce52009-01-03 21:22:43 +0000207
208 p = output;
209 DHM_MPI_EXPORT( &ctx->P , n1 );
210 DHM_MPI_EXPORT( &ctx->G , n2 );
211 DHM_MPI_EXPORT( &ctx->GX, n3 );
212
Hanno Beckere71ad122017-09-28 10:32:25 +0100213 *olen = p - output;
Paul Bakker5121ce52009-01-03 21:22:43 +0000214
215 ctx->len = n1;
216
217cleanup:
218
219 if( ret != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200220 return( MBEDTLS_ERR_DHM_MAKE_PARAMS_FAILED + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000221
222 return( 0 );
223}
224
225/*
Hanno Becker8880e752017-10-04 13:15:08 +0100226 * Set prime modulus and generator
227 */
228int mbedtls_dhm_set_group( mbedtls_dhm_context *ctx,
229 const mbedtls_mpi *P,
230 const mbedtls_mpi *G )
231{
232 int ret;
233
234 if( ctx == NULL || P == NULL || G == NULL )
235 return( MBEDTLS_ERR_DHM_BAD_INPUT_DATA );
236
237 if( ( ret = mbedtls_mpi_copy( &ctx->P, P ) ) != 0 ||
238 ( ret = mbedtls_mpi_copy( &ctx->G, G ) ) != 0 )
239 {
240 return( MBEDTLS_ERR_DHM_SET_GROUP_FAILED + ret );
241 }
242
243 ctx->len = mbedtls_mpi_size( &ctx->P );
244 return( 0 );
245}
246
247/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000248 * Import the peer's public value G^Y
249 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200250int mbedtls_dhm_read_public( mbedtls_dhm_context *ctx,
Paul Bakker23986e52011-04-24 08:57:21 +0000251 const unsigned char *input, size_t ilen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000252{
253 int ret;
254
255 if( ctx == NULL || ilen < 1 || ilen > ctx->len )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200256 return( MBEDTLS_ERR_DHM_BAD_INPUT_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +0000257
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200258 if( ( ret = mbedtls_mpi_read_binary( &ctx->GY, input, ilen ) ) != 0 )
259 return( MBEDTLS_ERR_DHM_READ_PUBLIC_FAILED + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000260
261 return( 0 );
262}
263
264/*
265 * Create own private value X and export G^X
266 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200267int mbedtls_dhm_make_public( mbedtls_dhm_context *ctx, int x_size,
Paul Bakker23986e52011-04-24 08:57:21 +0000268 unsigned char *output, size_t olen,
Paul Bakkera3d195c2011-11-27 21:07:34 +0000269 int (*f_rng)(void *, unsigned char *, size_t),
270 void *p_rng )
Paul Bakker5121ce52009-01-03 21:22:43 +0000271{
Paul Bakkeraec37cb2012-04-26 18:59:59 +0000272 int ret, count = 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000273
274 if( ctx == NULL || olen < 1 || olen > ctx->len )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200275 return( MBEDTLS_ERR_DHM_BAD_INPUT_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +0000276
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200277 if( mbedtls_mpi_cmp_int( &ctx->P, 0 ) == 0 )
278 return( MBEDTLS_ERR_DHM_BAD_INPUT_DATA );
Paul Bakkerb5b20f12012-09-16 15:07:49 +0000279
Paul Bakker5121ce52009-01-03 21:22:43 +0000280 /*
281 * generate X and calculate GX = G^X mod P
282 */
Paul Bakkeraec37cb2012-04-26 18:59:59 +0000283 do
284 {
Ron Eldor7269fee2017-01-12 14:50:50 +0200285 MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( &ctx->X, x_size, f_rng, p_rng ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000286
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200287 while( mbedtls_mpi_cmp_mpi( &ctx->X, &ctx->P ) >= 0 )
288 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &ctx->X, 1 ) );
Paul Bakkeraec37cb2012-04-26 18:59:59 +0000289
290 if( count++ > 10 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200291 return( MBEDTLS_ERR_DHM_MAKE_PUBLIC_FAILED );
Paul Bakkeraec37cb2012-04-26 18:59:59 +0000292 }
293 while( dhm_check_range( &ctx->X, &ctx->P ) != 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000294
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200295 MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &ctx->GX, &ctx->G, &ctx->X,
Paul Bakker5121ce52009-01-03 21:22:43 +0000296 &ctx->P , &ctx->RP ) );
297
Paul Bakker345a6fe2011-02-28 21:20:02 +0000298 if( ( ret = dhm_check_range( &ctx->GX, &ctx->P ) ) != 0 )
299 return( ret );
Paul Bakkerc47840e2011-02-20 16:37:30 +0000300
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200301 MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &ctx->GX, output, olen ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000302
303cleanup:
304
305 if( ret != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200306 return( MBEDTLS_ERR_DHM_MAKE_PUBLIC_FAILED + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000307
308 return( 0 );
309}
310
311/*
Manuel Pégourié-Gonnard143b5022013-09-04 16:29:59 +0200312 * Use the blinding method and optimisation suggested in section 10 of:
313 * KOCHER, Paul C. Timing attacks on implementations of Diffie-Hellman, RSA,
Manuel Pégourié-Gonnard998930a2015-04-03 13:48:06 +0200314 * DSS, and other systems. In : Advances in Cryptology-CRYPTO'96. Springer
Manuel Pégourié-Gonnard143b5022013-09-04 16:29:59 +0200315 * Berlin Heidelberg, 1996. p. 104-113.
316 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200317static int dhm_update_blinding( mbedtls_dhm_context *ctx,
Manuel Pégourié-Gonnard143b5022013-09-04 16:29:59 +0200318 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
319{
320 int ret, count;
321
322 /*
Manuel Pégourié-Gonnard15d5de12013-09-17 11:34:11 +0200323 * Don't use any blinding the first time a particular X is used,
324 * but remember it to use blinding next time.
Manuel Pégourié-Gonnard143b5022013-09-04 16:29:59 +0200325 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200326 if( mbedtls_mpi_cmp_mpi( &ctx->X, &ctx->pX ) != 0 )
Manuel Pégourié-Gonnarded8a02b2013-09-04 16:39:03 +0200327 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200328 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &ctx->pX, &ctx->X ) );
329 MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &ctx->Vi, 1 ) );
330 MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &ctx->Vf, 1 ) );
Manuel Pégourié-Gonnarded8a02b2013-09-04 16:39:03 +0200331
Manuel Pégourié-Gonnard143b5022013-09-04 16:29:59 +0200332 return( 0 );
333 }
334
335 /*
Manuel Pégourié-Gonnard15d5de12013-09-17 11:34:11 +0200336 * Ok, we need blinding. Can we re-use existing values?
337 * If yes, just update them by squaring them.
Manuel Pégourié-Gonnard143b5022013-09-04 16:29:59 +0200338 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200339 if( mbedtls_mpi_cmp_int( &ctx->Vi, 1 ) != 0 )
Manuel Pégourié-Gonnard15d5de12013-09-17 11:34:11 +0200340 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200341 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &ctx->Vi, &ctx->Vi, &ctx->Vi ) );
342 MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &ctx->Vi, &ctx->Vi, &ctx->P ) );
Manuel Pégourié-Gonnard15d5de12013-09-17 11:34:11 +0200343
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200344 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &ctx->Vf, &ctx->Vf, &ctx->Vf ) );
345 MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &ctx->Vf, &ctx->Vf, &ctx->P ) );
Manuel Pégourié-Gonnard15d5de12013-09-17 11:34:11 +0200346
347 return( 0 );
348 }
349
350 /*
351 * We need to generate blinding values from scratch
352 */
353
354 /* Vi = random( 2, P-1 ) */
355 count = 0;
356 do
357 {
Ron Eldor7269fee2017-01-12 14:50:50 +0200358 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 +0200359
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200360 while( mbedtls_mpi_cmp_mpi( &ctx->Vi, &ctx->P ) >= 0 )
361 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &ctx->Vi, 1 ) );
Manuel Pégourié-Gonnard15d5de12013-09-17 11:34:11 +0200362
363 if( count++ > 10 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200364 return( MBEDTLS_ERR_MPI_NOT_ACCEPTABLE );
Manuel Pégourié-Gonnard15d5de12013-09-17 11:34:11 +0200365 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200366 while( mbedtls_mpi_cmp_int( &ctx->Vi, 1 ) <= 0 );
Manuel Pégourié-Gonnard143b5022013-09-04 16:29:59 +0200367
Manuel Pégourié-Gonnard143b5022013-09-04 16:29:59 +0200368 /* Vf = Vi^-X mod P */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200369 MBEDTLS_MPI_CHK( mbedtls_mpi_inv_mod( &ctx->Vf, &ctx->Vi, &ctx->P ) );
370 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 +0200371
Manuel Pégourié-Gonnard143b5022013-09-04 16:29:59 +0200372cleanup:
373 return( ret );
374}
375
376/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000377 * Derive and export the shared secret (G^Y)^X mod P
378 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200379int mbedtls_dhm_calc_secret( mbedtls_dhm_context *ctx,
Manuel Pégourié-Gonnard33352052015-06-02 16:17:08 +0100380 unsigned char *output, size_t output_size, size_t *olen,
Manuel Pégourié-Gonnard2d627642013-09-04 14:22:07 +0200381 int (*f_rng)(void *, unsigned char *, size_t),
382 void *p_rng )
Paul Bakker5121ce52009-01-03 21:22:43 +0000383{
384 int ret;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200385 mbedtls_mpi GYb;
Manuel Pégourié-Gonnard2d627642013-09-04 14:22:07 +0200386
Manuel Pégourié-Gonnard33352052015-06-02 16:17:08 +0100387 if( ctx == NULL || output_size < ctx->len )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200388 return( MBEDTLS_ERR_DHM_BAD_INPUT_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +0000389
Paul Bakker345a6fe2011-02-28 21:20:02 +0000390 if( ( ret = dhm_check_range( &ctx->GY, &ctx->P ) ) != 0 )
Paul Bakkerc47840e2011-02-20 16:37:30 +0000391 return( ret );
392
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200393 mbedtls_mpi_init( &GYb );
Manuel Pégourié-Gonnard143b5022013-09-04 16:29:59 +0200394
395 /* Blind peer's value */
Manuel Pégourié-Gonnarded8a02b2013-09-04 16:39:03 +0200396 if( f_rng != NULL )
Manuel Pégourié-Gonnard143b5022013-09-04 16:29:59 +0200397 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200398 MBEDTLS_MPI_CHK( dhm_update_blinding( ctx, f_rng, p_rng ) );
399 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &GYb, &ctx->GY, &ctx->Vi ) );
400 MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &GYb, &GYb, &ctx->P ) );
Manuel Pégourié-Gonnard143b5022013-09-04 16:29:59 +0200401 }
402 else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200403 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &GYb, &ctx->GY ) );
Manuel Pégourié-Gonnard143b5022013-09-04 16:29:59 +0200404
405 /* Do modular exponentiation */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200406 MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &ctx->K, &GYb, &ctx->X,
Manuel Pégourié-Gonnard143b5022013-09-04 16:29:59 +0200407 &ctx->P, &ctx->RP ) );
408
409 /* Unblind secret value */
Manuel Pégourié-Gonnarded8a02b2013-09-04 16:39:03 +0200410 if( f_rng != NULL )
Manuel Pégourié-Gonnard143b5022013-09-04 16:29:59 +0200411 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200412 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &ctx->K, &ctx->K, &ctx->Vf ) );
413 MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &ctx->K, &ctx->K, &ctx->P ) );
Manuel Pégourié-Gonnard143b5022013-09-04 16:29:59 +0200414 }
415
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200416 *olen = mbedtls_mpi_size( &ctx->K );
Paul Bakker5121ce52009-01-03 21:22:43 +0000417
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200418 MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &ctx->K, output, *olen ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000419
420cleanup:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200421 mbedtls_mpi_free( &GYb );
Paul Bakker5121ce52009-01-03 21:22:43 +0000422
423 if( ret != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200424 return( MBEDTLS_ERR_DHM_CALC_SECRET_FAILED + ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000425
426 return( 0 );
427}
428
429/*
430 * Free the components of a DHM key
431 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200432void mbedtls_dhm_free( mbedtls_dhm_context *ctx )
Paul Bakker5121ce52009-01-03 21:22:43 +0000433{
Hanno Beckere71ad122017-09-28 10:32:25 +0100434 mbedtls_mpi_free( &ctx->pX ); mbedtls_mpi_free( &ctx->Vf );
435 mbedtls_mpi_free( &ctx->Vi ); mbedtls_mpi_free( &ctx->RP );
436 mbedtls_mpi_free( &ctx->K ); mbedtls_mpi_free( &ctx->GY );
437 mbedtls_mpi_free( &ctx->GX ); mbedtls_mpi_free( &ctx->X );
438 mbedtls_mpi_free( &ctx->G ); mbedtls_mpi_free( &ctx->P );
Manuel Pégourié-Gonnardb72b4ed2013-09-13 13:55:26 +0200439
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200440 mbedtls_zeroize( ctx, sizeof( mbedtls_dhm_context ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000441}
442
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200443#if defined(MBEDTLS_ASN1_PARSE_C)
Paul Bakker40ce79f2013-09-15 17:43:54 +0200444/*
445 * Parse DHM parameters
446 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200447int mbedtls_dhm_parse_dhm( mbedtls_dhm_context *dhm, const unsigned char *dhmin,
Paul Bakkerb9e4e2c2014-05-01 14:18:25 +0200448 size_t dhminlen )
Paul Bakker40ce79f2013-09-15 17:43:54 +0200449{
450 int ret;
451 size_t len;
452 unsigned char *p, *end;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200453#if defined(MBEDTLS_PEM_PARSE_C)
454 mbedtls_pem_context pem;
Paul Bakker40ce79f2013-09-15 17:43:54 +0200455
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200456 mbedtls_pem_init( &pem );
Paul Bakker40ce79f2013-09-15 17:43:54 +0200457
Manuel Pégourié-Gonnard43b37cb2015-05-12 11:20:10 +0200458 /* Avoid calling mbedtls_pem_read_buffer() on non-null-terminated string */
Manuel Pégourié-Gonnard0ece0f92015-05-12 12:43:54 +0200459 if( dhminlen == 0 || dhmin[dhminlen - 1] != '\0' )
Manuel Pégourié-Gonnard43b37cb2015-05-12 11:20:10 +0200460 ret = MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT;
461 else
462 ret = mbedtls_pem_read_buffer( &pem,
463 "-----BEGIN DH PARAMETERS-----",
464 "-----END DH PARAMETERS-----",
465 dhmin, NULL, 0, &dhminlen );
Paul Bakker40ce79f2013-09-15 17:43:54 +0200466
467 if( ret == 0 )
468 {
469 /*
470 * Was PEM encoded
471 */
472 dhminlen = pem.buflen;
473 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200474 else if( ret != MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
Paul Bakker40ce79f2013-09-15 17:43:54 +0200475 goto exit;
476
477 p = ( ret == 0 ) ? pem.buf : (unsigned char *) dhmin;
478#else
479 p = (unsigned char *) dhmin;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200480#endif /* MBEDTLS_PEM_PARSE_C */
Paul Bakker40ce79f2013-09-15 17:43:54 +0200481 end = p + dhminlen;
482
483 /*
484 * DHParams ::= SEQUENCE {
Daniel Kahn Gillmor2ed81732015-04-03 13:09:24 -0400485 * prime INTEGER, -- P
486 * generator INTEGER, -- g
487 * privateValueLength INTEGER OPTIONAL
Paul Bakker40ce79f2013-09-15 17:43:54 +0200488 * }
489 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200490 if( ( ret = mbedtls_asn1_get_tag( &p, end, &len,
491 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
Paul Bakker40ce79f2013-09-15 17:43:54 +0200492 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200493 ret = MBEDTLS_ERR_DHM_INVALID_FORMAT + ret;
Paul Bakker40ce79f2013-09-15 17:43:54 +0200494 goto exit;
495 }
496
497 end = p + len;
498
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200499 if( ( ret = mbedtls_asn1_get_mpi( &p, end, &dhm->P ) ) != 0 ||
500 ( ret = mbedtls_asn1_get_mpi( &p, end, &dhm->G ) ) != 0 )
Paul Bakker40ce79f2013-09-15 17:43:54 +0200501 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200502 ret = MBEDTLS_ERR_DHM_INVALID_FORMAT + ret;
Paul Bakker40ce79f2013-09-15 17:43:54 +0200503 goto exit;
504 }
505
506 if( p != end )
507 {
Manuel Pégourié-Gonnardde9b3632015-04-17 20:06:31 +0200508 /* This might be the optional privateValueLength.
509 * If so, we can cleanly discard it */
510 mbedtls_mpi rec;
511 mbedtls_mpi_init( &rec );
512 ret = mbedtls_asn1_get_mpi( &p, end, &rec );
513 mbedtls_mpi_free( &rec );
Daniel Kahn Gillmor2ed81732015-04-03 13:09:24 -0400514 if ( ret != 0 )
515 {
Manuel Pégourié-Gonnardde9b3632015-04-17 20:06:31 +0200516 ret = MBEDTLS_ERR_DHM_INVALID_FORMAT + ret;
Daniel Kahn Gillmor2ed81732015-04-03 13:09:24 -0400517 goto exit;
518 }
519 if ( p != end )
520 {
Manuel Pégourié-Gonnardde9b3632015-04-17 20:06:31 +0200521 ret = MBEDTLS_ERR_DHM_INVALID_FORMAT +
522 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH;
Daniel Kahn Gillmor2ed81732015-04-03 13:09:24 -0400523 goto exit;
524 }
Paul Bakker40ce79f2013-09-15 17:43:54 +0200525 }
526
527 ret = 0;
528
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200529 dhm->len = mbedtls_mpi_size( &dhm->P );
Manuel Pégourié-Gonnard3fec2202014-03-29 16:42:38 +0100530
Paul Bakker40ce79f2013-09-15 17:43:54 +0200531exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200532#if defined(MBEDTLS_PEM_PARSE_C)
533 mbedtls_pem_free( &pem );
Paul Bakker40ce79f2013-09-15 17:43:54 +0200534#endif
535 if( ret != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200536 mbedtls_dhm_free( dhm );
Paul Bakker40ce79f2013-09-15 17:43:54 +0200537
538 return( ret );
539}
540
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200541#if defined(MBEDTLS_FS_IO)
Paul Bakker40ce79f2013-09-15 17:43:54 +0200542/*
543 * Load all data from a file into a given buffer.
Manuel Pégourié-Gonnard43b37cb2015-05-12 11:20:10 +0200544 *
545 * The file is expected to contain either PEM or DER encoded data.
546 * A terminating null byte is always appended. It is included in the announced
547 * length only if the data looks like it is PEM encoded.
Paul Bakker40ce79f2013-09-15 17:43:54 +0200548 */
549static int load_file( const char *path, unsigned char **buf, size_t *n )
550{
551 FILE *f;
552 long size;
553
554 if( ( f = fopen( path, "rb" ) ) == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200555 return( MBEDTLS_ERR_DHM_FILE_IO_ERROR );
Paul Bakker40ce79f2013-09-15 17:43:54 +0200556
557 fseek( f, 0, SEEK_END );
558 if( ( size = ftell( f ) ) == -1 )
559 {
560 fclose( f );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200561 return( MBEDTLS_ERR_DHM_FILE_IO_ERROR );
Paul Bakker40ce79f2013-09-15 17:43:54 +0200562 }
563 fseek( f, 0, SEEK_SET );
564
565 *n = (size_t) size;
566
567 if( *n + 1 == 0 ||
Manuel Pégourié-Gonnard7551cb92015-05-26 16:04:06 +0200568 ( *buf = mbedtls_calloc( 1, *n + 1 ) ) == NULL )
Paul Bakker40ce79f2013-09-15 17:43:54 +0200569 {
570 fclose( f );
Manuel Pégourié-Gonnard6a8ca332015-05-28 09:33:39 +0200571 return( MBEDTLS_ERR_DHM_ALLOC_FAILED );
Paul Bakker40ce79f2013-09-15 17:43:54 +0200572 }
573
574 if( fread( *buf, 1, *n, f ) != *n )
575 {
576 fclose( f );
Andres Amaya Garciabdbca7b2017-06-23 16:23:21 +0100577
578 mbedtls_zeroize( *buf, *n + 1 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200579 mbedtls_free( *buf );
Andres Amaya Garciabdbca7b2017-06-23 16:23:21 +0100580
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200581 return( MBEDTLS_ERR_DHM_FILE_IO_ERROR );
Paul Bakker40ce79f2013-09-15 17:43:54 +0200582 }
583
584 fclose( f );
585
586 (*buf)[*n] = '\0';
587
Manuel Pégourié-Gonnard43b37cb2015-05-12 11:20:10 +0200588 if( strstr( (const char *) *buf, "-----BEGIN " ) != NULL )
589 ++*n;
590
Paul Bakker40ce79f2013-09-15 17:43:54 +0200591 return( 0 );
592}
593
594/*
595 * Load and parse DHM parameters
596 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200597int mbedtls_dhm_parse_dhmfile( mbedtls_dhm_context *dhm, const char *path )
Paul Bakker40ce79f2013-09-15 17:43:54 +0200598{
599 int ret;
600 size_t n;
601 unsigned char *buf;
602
Paul Bakker66d5d072014-06-17 16:39:18 +0200603 if( ( ret = load_file( path, &buf, &n ) ) != 0 )
Paul Bakker40ce79f2013-09-15 17:43:54 +0200604 return( ret );
605
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200606 ret = mbedtls_dhm_parse_dhm( dhm, buf, n );
Paul Bakker40ce79f2013-09-15 17:43:54 +0200607
Manuel Pégourié-Gonnard43b37cb2015-05-12 11:20:10 +0200608 mbedtls_zeroize( buf, n );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200609 mbedtls_free( buf );
Paul Bakker40ce79f2013-09-15 17:43:54 +0200610
611 return( ret );
612}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200613#endif /* MBEDTLS_FS_IO */
614#endif /* MBEDTLS_ASN1_PARSE_C */
nirekh0149762fa2017-12-25 06:46:48 +0000615#endif /* MBEDTLS_DHM_ALT */
Paul Bakker40ce79f2013-09-15 17:43:54 +0200616
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200617#if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +0000618
Manuel Pégourié-Gonnard53585ee2015-06-25 08:52:25 +0200619static const char mbedtls_test_dhm_params[] =
620"-----BEGIN DH PARAMETERS-----\r\n"
621"MIGHAoGBAJ419DBEOgmQTzo5qXl5fQcN9TN455wkOL7052HzxxRVMyhYmwQcgJvh\r\n"
622"1sa18fyfR9OiVEMYglOpkqVoGLN7qd5aQNNi5W7/C+VBdHTBJcGZJyyP5B3qcz32\r\n"
623"9mLJKudlVudV0Qxk5qUJaPZ/xupz0NyoVpviuiBOI1gNi8ovSXWzAgEC\r\n"
624"-----END DH PARAMETERS-----\r\n";
625
626static const size_t mbedtls_test_dhm_params_len = sizeof( mbedtls_test_dhm_params );
Paul Bakker40ce79f2013-09-15 17:43:54 +0200627
Paul Bakker5121ce52009-01-03 21:22:43 +0000628/*
629 * Checkup routine
630 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200631int mbedtls_dhm_self_test( int verbose )
Paul Bakker5121ce52009-01-03 21:22:43 +0000632{
Paul Bakker40ce79f2013-09-15 17:43:54 +0200633 int ret;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200634 mbedtls_dhm_context dhm;
Paul Bakker40ce79f2013-09-15 17:43:54 +0200635
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200636 mbedtls_dhm_init( &dhm );
Paul Bakker8f870b02014-06-20 13:32:38 +0200637
Paul Bakker40ce79f2013-09-15 17:43:54 +0200638 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200639 mbedtls_printf( " DHM parameter load: " );
Paul Bakker40ce79f2013-09-15 17:43:54 +0200640
Manuel Pégourié-Gonnard53585ee2015-06-25 08:52:25 +0200641 if( ( ret = mbedtls_dhm_parse_dhm( &dhm,
642 (const unsigned char *) mbedtls_test_dhm_params,
643 mbedtls_test_dhm_params_len ) ) != 0 )
Paul Bakker40ce79f2013-09-15 17:43:54 +0200644 {
645 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200646 mbedtls_printf( "failed\n" );
Paul Bakker40ce79f2013-09-15 17:43:54 +0200647
Manuel Pégourié-Gonnardb196fc22014-07-09 16:53:29 +0200648 ret = 1;
Paul Bakker8f870b02014-06-20 13:32:38 +0200649 goto exit;
Paul Bakker40ce79f2013-09-15 17:43:54 +0200650 }
651
652 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200653 mbedtls_printf( "passed\n\n" );
Paul Bakker40ce79f2013-09-15 17:43:54 +0200654
Paul Bakker8f870b02014-06-20 13:32:38 +0200655exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200656 mbedtls_dhm_free( &dhm );
Paul Bakker40ce79f2013-09-15 17:43:54 +0200657
Paul Bakker8f870b02014-06-20 13:32:38 +0200658 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000659}
660
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200661#endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +0000662
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200663#endif /* MBEDTLS_DHM_C */