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