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.
Dependencies: nRF51_Vdd TextLCD BME280
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 15:15:42 by
