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