Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
dhm.c
00001 /* 00002 * Diffie-Hellman-Merkle key exchange 00003 * 00004 * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved 00005 * SPDX-License-Identifier: Apache-2.0 00006 * 00007 * Licensed under the Apache License, Version 2.0 (the "License"); you may 00008 * not use this file except in compliance with the License. 00009 * You may obtain a copy of the License at 00010 * 00011 * http://www.apache.org/licenses/LICENSE-2.0 00012 * 00013 * Unless required by applicable law or agreed to in writing, software 00014 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 00015 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00016 * See the License for the specific language governing permissions and 00017 * limitations under the License. 00018 * 00019 * This file is part of mbed TLS (https://tls.mbed.org) 00020 */ 00021 /* 00022 * The following sources were referenced in the design of this implementation 00023 * of the Diffie-Hellman-Merkle algorithm: 00024 * 00025 * [1] Handbook of Applied Cryptography - 1997, Chapter 12 00026 * Menezes, van Oorschot and Vanstone 00027 * 00028 */ 00029 00030 #if !defined(MBEDTLS_CONFIG_FILE) 00031 #include "mbedtls/config.h" 00032 #else 00033 #include MBEDTLS_CONFIG_FILE 00034 #endif 00035 00036 #if defined(MBEDTLS_DHM_C) 00037 00038 #include "mbedtls/dhm.h" 00039 00040 #include <string.h> 00041 00042 #if defined(MBEDTLS_PEM_PARSE_C) 00043 #include "mbedtls/pem.h" 00044 #endif 00045 00046 #if defined(MBEDTLS_ASN1_PARSE_C) 00047 #include "mbedtls/asn1.h" 00048 #endif 00049 00050 #if defined(MBEDTLS_PLATFORM_C) 00051 #include "mbedtls/platform.h" 00052 #else 00053 #include <stdlib.h> 00054 #include <stdio.h> 00055 #define mbedtls_printf printf 00056 #define mbedtls_calloc calloc 00057 #define mbedtls_free free 00058 #endif 00059 00060 #if !defined(MBEDTLS_DHM_ALT) 00061 /* Implementation that should never be optimized out by the compiler */ 00062 static void mbedtls_zeroize( void *v, size_t n ) { 00063 volatile unsigned char *p = v; while( n-- ) *p++ = 0; 00064 } 00065 00066 /* 00067 * helper to validate the mbedtls_mpi size and import it 00068 */ 00069 static int dhm_read_bignum( mbedtls_mpi *X, 00070 unsigned char **p, 00071 const unsigned char *end ) 00072 { 00073 int ret, n; 00074 00075 if( end - *p < 2 ) 00076 return( MBEDTLS_ERR_DHM_BAD_INPUT_DATA ); 00077 00078 n = ( (*p)[0] << 8 ) | (*p)[1]; 00079 (*p) += 2; 00080 00081 if( (int)( end - *p ) < n ) 00082 return( MBEDTLS_ERR_DHM_BAD_INPUT_DATA ); 00083 00084 if( ( ret = mbedtls_mpi_read_binary( X, *p, n ) ) != 0 ) 00085 return( MBEDTLS_ERR_DHM_READ_PARAMS_FAILED + ret ); 00086 00087 (*p) += n; 00088 00089 return( 0 ); 00090 } 00091 00092 /* 00093 * Verify sanity of parameter with regards to P 00094 * 00095 * Parameter should be: 2 <= public_param <= P - 2 00096 * 00097 * This means that we need to return an error if 00098 * public_param < 2 or public_param > P-2 00099 * 00100 * For more information on the attack, see: 00101 * http://www.cl.cam.ac.uk/~rja14/Papers/psandqs.pdf 00102 * http://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2005-2643 00103 */ 00104 static int dhm_check_range( const mbedtls_mpi *param, const mbedtls_mpi *P ) 00105 { 00106 mbedtls_mpi L, U; 00107 int ret = 0; 00108 00109 mbedtls_mpi_init( &L ); mbedtls_mpi_init( &U ); 00110 00111 MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &L, 2 ) ); 00112 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &U, P, 2 ) ); 00113 00114 if( mbedtls_mpi_cmp_mpi( param, &L ) < 0 || 00115 mbedtls_mpi_cmp_mpi( param, &U ) > 0 ) 00116 { 00117 ret = MBEDTLS_ERR_DHM_BAD_INPUT_DATA; 00118 } 00119 00120 cleanup: 00121 mbedtls_mpi_free( &L ); mbedtls_mpi_free( &U ); 00122 return( ret ); 00123 } 00124 00125 void mbedtls_dhm_init( mbedtls_dhm_context *ctx ) 00126 { 00127 memset( ctx, 0, sizeof( mbedtls_dhm_context ) ); 00128 } 00129 00130 /* 00131 * Parse the ServerKeyExchange parameters 00132 */ 00133 int mbedtls_dhm_read_params( mbedtls_dhm_context *ctx, 00134 unsigned char **p, 00135 const unsigned char *end ) 00136 { 00137 int ret; 00138 00139 if( ( ret = dhm_read_bignum( &ctx->P , p, end ) ) != 0 || 00140 ( ret = dhm_read_bignum( &ctx->G , p, end ) ) != 0 || 00141 ( ret = dhm_read_bignum( &ctx->GY , p, end ) ) != 0 ) 00142 return( ret ); 00143 00144 if( ( ret = dhm_check_range( &ctx->GY , &ctx->P ) ) != 0 ) 00145 return( ret ); 00146 00147 ctx->len = mbedtls_mpi_size( &ctx->P ); 00148 00149 return( 0 ); 00150 } 00151 00152 /* 00153 * Setup and write the ServerKeyExchange parameters 00154 */ 00155 int mbedtls_dhm_make_params( mbedtls_dhm_context *ctx, int x_size, 00156 unsigned char *output, size_t *olen, 00157 int (*f_rng)(void *, unsigned char *, size_t), 00158 void *p_rng ) 00159 { 00160 int ret, count = 0; 00161 size_t n1, n2, n3; 00162 unsigned char *p; 00163 00164 if( mbedtls_mpi_cmp_int( &ctx->P , 0 ) == 0 ) 00165 return( MBEDTLS_ERR_DHM_BAD_INPUT_DATA ); 00166 00167 /* 00168 * Generate X as large as possible ( < P ) 00169 */ 00170 do 00171 { 00172 MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( &ctx->X , x_size, f_rng, p_rng ) ); 00173 00174 while( mbedtls_mpi_cmp_mpi( &ctx->X , &ctx->P ) >= 0 ) 00175 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &ctx->X , 1 ) ); 00176 00177 if( count++ > 10 ) 00178 return( MBEDTLS_ERR_DHM_MAKE_PARAMS_FAILED ); 00179 } 00180 while( dhm_check_range( &ctx->X , &ctx->P ) != 0 ); 00181 00182 /* 00183 * Calculate GX = G^X mod P 00184 */ 00185 MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &ctx->GX , &ctx->G , &ctx->X , 00186 &ctx->P , &ctx->RP ) ); 00187 00188 if( ( ret = dhm_check_range( &ctx->GX , &ctx->P ) ) != 0 ) 00189 return( ret ); 00190 00191 /* 00192 * export P, G, GX 00193 */ 00194 #define DHM_MPI_EXPORT( X, n ) \ 00195 do { \ 00196 MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( ( X ), \ 00197 p + 2, \ 00198 ( n ) ) ); \ 00199 *p++ = (unsigned char)( ( n ) >> 8 ); \ 00200 *p++ = (unsigned char)( ( n ) ); \ 00201 p += ( n ); \ 00202 } while( 0 ) 00203 00204 n1 = mbedtls_mpi_size( &ctx->P ); 00205 n2 = mbedtls_mpi_size( &ctx->G ); 00206 n3 = mbedtls_mpi_size( &ctx->GX ); 00207 00208 p = output; 00209 DHM_MPI_EXPORT( &ctx->P , n1 ); 00210 DHM_MPI_EXPORT( &ctx->G , n2 ); 00211 DHM_MPI_EXPORT( &ctx->GX , n3 ); 00212 00213 *olen = p - output; 00214 00215 ctx->len = n1; 00216 00217 cleanup: 00218 00219 if( ret != 0 ) 00220 return( MBEDTLS_ERR_DHM_MAKE_PARAMS_FAILED + ret ); 00221 00222 return( 0 ); 00223 } 00224 00225 /* 00226 * Set prime modulus and generator 00227 */ 00228 int mbedtls_dhm_set_group( mbedtls_dhm_context *ctx, 00229 const mbedtls_mpi *P, 00230 const mbedtls_mpi *G ) 00231 { 00232 int ret; 00233 00234 if( ctx == NULL || P == NULL || G == NULL ) 00235 return( MBEDTLS_ERR_DHM_BAD_INPUT_DATA ); 00236 00237 if( ( ret = mbedtls_mpi_copy( &ctx->P , P ) ) != 0 || 00238 ( ret = mbedtls_mpi_copy( &ctx->G , G ) ) != 0 ) 00239 { 00240 return( MBEDTLS_ERR_DHM_SET_GROUP_FAILED + ret ); 00241 } 00242 00243 ctx->len = mbedtls_mpi_size( &ctx->P ); 00244 return( 0 ); 00245 } 00246 00247 /* 00248 * Import the peer's public value G^Y 00249 */ 00250 int mbedtls_dhm_read_public( mbedtls_dhm_context *ctx, 00251 const unsigned char *input, size_t ilen ) 00252 { 00253 int ret; 00254 00255 if( ctx == NULL || ilen < 1 || ilen > ctx->len ) 00256 return( MBEDTLS_ERR_DHM_BAD_INPUT_DATA ); 00257 00258 if( ( ret = mbedtls_mpi_read_binary( &ctx->GY , input, ilen ) ) != 0 ) 00259 return( MBEDTLS_ERR_DHM_READ_PUBLIC_FAILED + ret ); 00260 00261 return( 0 ); 00262 } 00263 00264 /* 00265 * Create own private value X and export G^X 00266 */ 00267 int mbedtls_dhm_make_public( mbedtls_dhm_context *ctx, int x_size, 00268 unsigned char *output, size_t olen, 00269 int (*f_rng)(void *, unsigned char *, size_t), 00270 void *p_rng ) 00271 { 00272 int ret, count = 0; 00273 00274 if( ctx == NULL || olen < 1 || olen > ctx->len ) 00275 return( MBEDTLS_ERR_DHM_BAD_INPUT_DATA ); 00276 00277 if( mbedtls_mpi_cmp_int( &ctx->P , 0 ) == 0 ) 00278 return( MBEDTLS_ERR_DHM_BAD_INPUT_DATA ); 00279 00280 /* 00281 * generate X and calculate GX = G^X mod P 00282 */ 00283 do 00284 { 00285 MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( &ctx->X , x_size, f_rng, p_rng ) ); 00286 00287 while( mbedtls_mpi_cmp_mpi( &ctx->X , &ctx->P ) >= 0 ) 00288 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &ctx->X , 1 ) ); 00289 00290 if( count++ > 10 ) 00291 return( MBEDTLS_ERR_DHM_MAKE_PUBLIC_FAILED ); 00292 } 00293 while( dhm_check_range( &ctx->X , &ctx->P ) != 0 ); 00294 00295 MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &ctx->GX , &ctx->G , &ctx->X , 00296 &ctx->P , &ctx->RP ) ); 00297 00298 if( ( ret = dhm_check_range( &ctx->GX , &ctx->P ) ) != 0 ) 00299 return( ret ); 00300 00301 MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &ctx->GX , output, olen ) ); 00302 00303 cleanup: 00304 00305 if( ret != 0 ) 00306 return( MBEDTLS_ERR_DHM_MAKE_PUBLIC_FAILED + ret ); 00307 00308 return( 0 ); 00309 } 00310 00311 /* 00312 * Use the blinding method and optimisation suggested in section 10 of: 00313 * KOCHER, Paul C. Timing attacks on implementations of Diffie-Hellman, RSA, 00314 * DSS, and other systems. In : Advances in Cryptology-CRYPTO'96. Springer 00315 * Berlin Heidelberg, 1996. p. 104-113. 00316 */ 00317 static int dhm_update_blinding( mbedtls_dhm_context *ctx, 00318 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ) 00319 { 00320 int ret, count; 00321 00322 /* 00323 * Don't use any blinding the first time a particular X is used, 00324 * but remember it to use blinding next time. 00325 */ 00326 if( mbedtls_mpi_cmp_mpi( &ctx->X , &ctx->pX ) != 0 ) 00327 { 00328 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &ctx->pX , &ctx->X ) ); 00329 MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &ctx->Vi , 1 ) ); 00330 MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &ctx->Vf , 1 ) ); 00331 00332 return( 0 ); 00333 } 00334 00335 /* 00336 * Ok, we need blinding. Can we re-use existing values? 00337 * If yes, just update them by squaring them. 00338 */ 00339 if( mbedtls_mpi_cmp_int( &ctx->Vi , 1 ) != 0 ) 00340 { 00341 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &ctx->Vi , &ctx->Vi , &ctx->Vi ) ); 00342 MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &ctx->Vi , &ctx->Vi , &ctx->P ) ); 00343 00344 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &ctx->Vf , &ctx->Vf , &ctx->Vf ) ); 00345 MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &ctx->Vf , &ctx->Vf , &ctx->P ) ); 00346 00347 return( 0 ); 00348 } 00349 00350 /* 00351 * We need to generate blinding values from scratch 00352 */ 00353 00354 /* Vi = random( 2, P-1 ) */ 00355 count = 0; 00356 do 00357 { 00358 MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( &ctx->Vi , mbedtls_mpi_size( &ctx->P ), f_rng, p_rng ) ); 00359 00360 while( mbedtls_mpi_cmp_mpi( &ctx->Vi , &ctx->P ) >= 0 ) 00361 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &ctx->Vi , 1 ) ); 00362 00363 if( count++ > 10 ) 00364 return( MBEDTLS_ERR_MPI_NOT_ACCEPTABLE ); 00365 } 00366 while( mbedtls_mpi_cmp_int( &ctx->Vi , 1 ) <= 0 ); 00367 00368 /* Vf = Vi^-X mod P */ 00369 MBEDTLS_MPI_CHK( mbedtls_mpi_inv_mod( &ctx->Vf , &ctx->Vi , &ctx->P ) ); 00370 MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &ctx->Vf , &ctx->Vf , &ctx->X , &ctx->P , &ctx->RP ) ); 00371 00372 cleanup: 00373 return( ret ); 00374 } 00375 00376 /* 00377 * Derive and export the shared secret (G^Y)^X mod P 00378 */ 00379 int mbedtls_dhm_calc_secret( mbedtls_dhm_context *ctx, 00380 unsigned char *output, size_t output_size, size_t *olen, 00381 int (*f_rng)(void *, unsigned char *, size_t), 00382 void *p_rng ) 00383 { 00384 int ret; 00385 mbedtls_mpi GYb; 00386 00387 if( ctx == NULL || output_size < ctx->len ) 00388 return( MBEDTLS_ERR_DHM_BAD_INPUT_DATA ); 00389 00390 if( ( ret = dhm_check_range( &ctx->GY , &ctx->P ) ) != 0 ) 00391 return( ret ); 00392 00393 mbedtls_mpi_init( &GYb ); 00394 00395 /* Blind peer's value */ 00396 if( f_rng != NULL ) 00397 { 00398 MBEDTLS_MPI_CHK( dhm_update_blinding( ctx, f_rng, p_rng ) ); 00399 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &GYb, &ctx->GY , &ctx->Vi ) ); 00400 MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &GYb, &GYb, &ctx->P ) ); 00401 } 00402 else 00403 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &GYb, &ctx->GY ) ); 00404 00405 /* Do modular exponentiation */ 00406 MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &ctx->K , &GYb, &ctx->X , 00407 &ctx->P , &ctx->RP ) ); 00408 00409 /* Unblind secret value */ 00410 if( f_rng != NULL ) 00411 { 00412 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &ctx->K , &ctx->K , &ctx->Vf ) ); 00413 MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &ctx->K , &ctx->K , &ctx->P ) ); 00414 } 00415 00416 *olen = mbedtls_mpi_size( &ctx->K ); 00417 00418 MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &ctx->K , output, *olen ) ); 00419 00420 cleanup: 00421 mbedtls_mpi_free( &GYb ); 00422 00423 if( ret != 0 ) 00424 return( MBEDTLS_ERR_DHM_CALC_SECRET_FAILED + ret ); 00425 00426 return( 0 ); 00427 } 00428 00429 /* 00430 * Free the components of a DHM key 00431 */ 00432 void mbedtls_dhm_free( mbedtls_dhm_context *ctx ) 00433 { 00434 mbedtls_mpi_free( &ctx->pX ); mbedtls_mpi_free( &ctx->Vf ); 00435 mbedtls_mpi_free( &ctx->Vi ); mbedtls_mpi_free( &ctx->RP ); 00436 mbedtls_mpi_free( &ctx->K ); mbedtls_mpi_free( &ctx->GY ); 00437 mbedtls_mpi_free( &ctx->GX ); mbedtls_mpi_free( &ctx->X ); 00438 mbedtls_mpi_free( &ctx->G ); mbedtls_mpi_free( &ctx->P ); 00439 00440 mbedtls_zeroize( ctx, sizeof( mbedtls_dhm_context ) ); 00441 } 00442 00443 #if defined(MBEDTLS_ASN1_PARSE_C) 00444 /* 00445 * Parse DHM parameters 00446 */ 00447 int mbedtls_dhm_parse_dhm( mbedtls_dhm_context *dhm, const unsigned char *dhmin, 00448 size_t dhminlen ) 00449 { 00450 int ret; 00451 size_t len; 00452 unsigned char *p, *end; 00453 #if defined(MBEDTLS_PEM_PARSE_C) 00454 mbedtls_pem_context pem; 00455 00456 mbedtls_pem_init( &pem ); 00457 00458 /* Avoid calling mbedtls_pem_read_buffer() on non-null-terminated string */ 00459 if( dhminlen == 0 || dhmin[dhminlen - 1] != '\0' ) 00460 ret = MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT; 00461 else 00462 ret = mbedtls_pem_read_buffer( &pem, 00463 "-----BEGIN DH PARAMETERS-----", 00464 "-----END DH PARAMETERS-----", 00465 dhmin, NULL, 0, &dhminlen ); 00466 00467 if( ret == 0 ) 00468 { 00469 /* 00470 * Was PEM encoded 00471 */ 00472 dhminlen = pem.buflen ; 00473 } 00474 else if( ret != MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT ) 00475 goto exit; 00476 00477 p = ( ret == 0 ) ? pem.buf : (unsigned char *) dhmin; 00478 #else 00479 p = (unsigned char *) dhmin; 00480 #endif /* MBEDTLS_PEM_PARSE_C */ 00481 end = p + dhminlen; 00482 00483 /* 00484 * DHParams ::= SEQUENCE { 00485 * prime INTEGER, -- P 00486 * generator INTEGER, -- g 00487 * privateValueLength INTEGER OPTIONAL 00488 * } 00489 */ 00490 if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, 00491 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 ) 00492 { 00493 ret = MBEDTLS_ERR_DHM_INVALID_FORMAT + ret; 00494 goto exit; 00495 } 00496 00497 end = p + len; 00498 00499 if( ( ret = mbedtls_asn1_get_mpi( &p, end, &dhm->P ) ) != 0 || 00500 ( ret = mbedtls_asn1_get_mpi( &p, end, &dhm->G ) ) != 0 ) 00501 { 00502 ret = MBEDTLS_ERR_DHM_INVALID_FORMAT + ret; 00503 goto exit; 00504 } 00505 00506 if( p != end ) 00507 { 00508 /* This might be the optional privateValueLength. 00509 * If so, we can cleanly discard it */ 00510 mbedtls_mpi rec; 00511 mbedtls_mpi_init( &rec ); 00512 ret = mbedtls_asn1_get_mpi( &p, end, &rec ); 00513 mbedtls_mpi_free( &rec ); 00514 if ( ret != 0 ) 00515 { 00516 ret = MBEDTLS_ERR_DHM_INVALID_FORMAT + ret; 00517 goto exit; 00518 } 00519 if ( p != end ) 00520 { 00521 ret = MBEDTLS_ERR_DHM_INVALID_FORMAT + 00522 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH; 00523 goto exit; 00524 } 00525 } 00526 00527 ret = 0; 00528 00529 dhm->len = mbedtls_mpi_size( &dhm->P ); 00530 00531 exit: 00532 #if defined(MBEDTLS_PEM_PARSE_C) 00533 mbedtls_pem_free( &pem ); 00534 #endif 00535 if( ret != 0 ) 00536 mbedtls_dhm_free( dhm ); 00537 00538 return( ret ); 00539 } 00540 00541 #if defined(MBEDTLS_FS_IO) 00542 /* 00543 * Load all data from a file into a given buffer. 00544 * 00545 * The file is expected to contain either PEM or DER encoded data. 00546 * A terminating null byte is always appended. It is included in the announced 00547 * length only if the data looks like it is PEM encoded. 00548 */ 00549 static int load_file( const char *path, unsigned char **buf, size_t *n ) 00550 { 00551 FILE *f; 00552 long size; 00553 00554 if( ( f = fopen( path, "rb" ) ) == NULL ) 00555 return( MBEDTLS_ERR_DHM_FILE_IO_ERROR ); 00556 00557 fseek( f, 0, SEEK_END ); 00558 if( ( size = ftell( f ) ) == -1 ) 00559 { 00560 fclose( f ); 00561 return( MBEDTLS_ERR_DHM_FILE_IO_ERROR ); 00562 } 00563 fseek( f, 0, SEEK_SET ); 00564 00565 *n = (size_t) size; 00566 00567 if( *n + 1 == 0 || 00568 ( *buf = mbedtls_calloc( 1, *n + 1 ) ) == NULL ) 00569 { 00570 fclose( f ); 00571 return( MBEDTLS_ERR_DHM_ALLOC_FAILED ); 00572 } 00573 00574 if( fread( *buf, 1, *n, f ) != *n ) 00575 { 00576 fclose( f ); 00577 00578 mbedtls_zeroize( *buf, *n + 1 ); 00579 mbedtls_free( *buf ); 00580 00581 return( MBEDTLS_ERR_DHM_FILE_IO_ERROR ); 00582 } 00583 00584 fclose( f ); 00585 00586 (*buf)[*n] = '\0'; 00587 00588 if( strstr( (const char *) *buf, "-----BEGIN " ) != NULL ) 00589 ++*n; 00590 00591 return( 0 ); 00592 } 00593 00594 /* 00595 * Load and parse DHM parameters 00596 */ 00597 int mbedtls_dhm_parse_dhmfile( mbedtls_dhm_context *dhm, const char *path ) 00598 { 00599 int ret; 00600 size_t n; 00601 unsigned char *buf; 00602 00603 if( ( ret = load_file( path, &buf, &n ) ) != 0 ) 00604 return( ret ); 00605 00606 ret = mbedtls_dhm_parse_dhm( dhm, buf, n ); 00607 00608 mbedtls_zeroize( buf, n ); 00609 mbedtls_free( buf ); 00610 00611 return( ret ); 00612 } 00613 #endif /* MBEDTLS_FS_IO */ 00614 #endif /* MBEDTLS_ASN1_PARSE_C */ 00615 #endif /* MBEDTLS_DHM_ALT */ 00616 00617 #if defined(MBEDTLS_SELF_TEST) 00618 00619 static const char mbedtls_test_dhm_params[] = 00620 "-----BEGIN DH PARAMETERS-----\r\n" 00621 "MIGHAoGBAJ419DBEOgmQTzo5qXl5fQcN9TN455wkOL7052HzxxRVMyhYmwQcgJvh\r\n" 00622 "1sa18fyfR9OiVEMYglOpkqVoGLN7qd5aQNNi5W7/C+VBdHTBJcGZJyyP5B3qcz32\r\n" 00623 "9mLJKudlVudV0Qxk5qUJaPZ/xupz0NyoVpviuiBOI1gNi8ovSXWzAgEC\r\n" 00624 "-----END DH PARAMETERS-----\r\n"; 00625 00626 static const size_t mbedtls_test_dhm_params_len = sizeof( mbedtls_test_dhm_params ); 00627 00628 /* 00629 * Checkup routine 00630 */ 00631 int mbedtls_dhm_self_test( int verbose ) 00632 { 00633 int ret; 00634 mbedtls_dhm_context dhm; 00635 00636 mbedtls_dhm_init( &dhm ); 00637 00638 if( verbose != 0 ) 00639 mbedtls_printf( " DHM parameter load: " ); 00640 00641 if( ( ret = mbedtls_dhm_parse_dhm( &dhm, 00642 (const unsigned char *) mbedtls_test_dhm_params, 00643 mbedtls_test_dhm_params_len ) ) != 0 ) 00644 { 00645 if( verbose != 0 ) 00646 mbedtls_printf( "failed\n" ); 00647 00648 ret = 1; 00649 goto exit; 00650 } 00651 00652 if( verbose != 0 ) 00653 mbedtls_printf( "passed\n\n" ); 00654 00655 exit: 00656 mbedtls_dhm_free( &dhm ); 00657 00658 return( ret ); 00659 } 00660 00661 #endif /* MBEDTLS_SELF_TEST */ 00662 00663 #endif /* MBEDTLS_DHM_C */
Generated on Tue Jul 12 2022 18:18:31 by
