mbedtls ported to mbed-classic
Fork of mbedtls by
Embed:
(wiki syntax)
Show/hide line numbers
ctr_drbg.c
00001 /* 00002 * CTR_DRBG implementation based on AES-256 (NIST SP 800-90) 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 NIST SP 800-90 DRBGs are described in the following publucation. 00023 * 00024 * http://csrc.nist.gov/publications/nistpubs/800-90/SP800-90revised_March2007.pdf 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_CTR_DRBG_C) 00034 00035 #include "mbedtls/ctr_drbg.h" 00036 00037 #include <string.h> 00038 00039 #if defined(MBEDTLS_FS_IO) 00040 #include <stdio.h> 00041 #endif 00042 00043 #if defined(MBEDTLS_SELF_TEST) 00044 #if defined(MBEDTLS_PLATFORM_C) 00045 #include "mbedtls/platform.h" 00046 #else 00047 #include <stdio.h> 00048 #define mbedtls_printf printf 00049 #endif /* MBEDTLS_PLATFORM_C */ 00050 #endif /* MBEDTLS_SELF_TEST */ 00051 00052 /* Implementation that should never be optimized out by the compiler */ 00053 static void mbedtls_zeroize( void *v, size_t n ) { 00054 volatile unsigned char *p = v; while( n-- ) *p++ = 0; 00055 } 00056 00057 /* 00058 * CTR_DRBG context initialization 00059 */ 00060 void mbedtls_ctr_drbg_init( mbedtls_ctr_drbg_context *ctx ) 00061 { 00062 memset( ctx, 0, sizeof( mbedtls_ctr_drbg_context ) ); 00063 00064 #if defined(MBEDTLS_THREADING_C) 00065 mbedtls_mutex_init( &ctx->mutex ); 00066 #endif 00067 } 00068 00069 /* 00070 * Non-public function wrapped by ctr_crbg_init(). Necessary to allow NIST 00071 * tests to succeed (which require known length fixed entropy) 00072 */ 00073 int mbedtls_ctr_drbg_seed_entropy_len( 00074 mbedtls_ctr_drbg_context *ctx, 00075 int (*f_entropy)(void *, unsigned char *, size_t), 00076 void *p_entropy, 00077 const unsigned char *custom, 00078 size_t len, 00079 size_t entropy_len ) 00080 { 00081 int ret; 00082 unsigned char key[MBEDTLS_CTR_DRBG_KEYSIZE]; 00083 00084 memset( key, 0, MBEDTLS_CTR_DRBG_KEYSIZE ); 00085 00086 mbedtls_aes_init( &ctx->aes_ctx ); 00087 00088 ctx->f_entropy = f_entropy; 00089 ctx->p_entropy = p_entropy; 00090 00091 ctx->entropy_len = entropy_len; 00092 ctx->reseed_interval = MBEDTLS_CTR_DRBG_RESEED_INTERVAL; 00093 00094 /* 00095 * Initialize with an empty key 00096 */ 00097 mbedtls_aes_setkey_enc( &ctx->aes_ctx , key, MBEDTLS_CTR_DRBG_KEYBITS ); 00098 00099 if( ( ret = mbedtls_ctr_drbg_reseed( ctx, custom, len ) ) != 0 ) 00100 return( ret ); 00101 00102 return( 0 ); 00103 } 00104 00105 int mbedtls_ctr_drbg_seed( mbedtls_ctr_drbg_context *ctx, 00106 int (*f_entropy)(void *, unsigned char *, size_t), 00107 void *p_entropy, 00108 const unsigned char *custom, 00109 size_t len ) 00110 { 00111 return( mbedtls_ctr_drbg_seed_entropy_len( ctx, f_entropy, p_entropy, custom, len, 00112 MBEDTLS_CTR_DRBG_ENTROPY_LEN ) ); 00113 } 00114 00115 void mbedtls_ctr_drbg_free( mbedtls_ctr_drbg_context *ctx ) 00116 { 00117 if( ctx == NULL ) 00118 return; 00119 00120 #if defined(MBEDTLS_THREADING_C) 00121 mbedtls_mutex_free( &ctx->mutex ); 00122 #endif 00123 mbedtls_aes_free( &ctx->aes_ctx ); 00124 mbedtls_zeroize( ctx, sizeof( mbedtls_ctr_drbg_context ) ); 00125 } 00126 00127 void mbedtls_ctr_drbg_set_prediction_resistance( mbedtls_ctr_drbg_context *ctx, int resistance ) 00128 { 00129 ctx->prediction_resistance = resistance; 00130 } 00131 00132 void mbedtls_ctr_drbg_set_entropy_len( mbedtls_ctr_drbg_context *ctx, size_t len ) 00133 { 00134 ctx->entropy_len = len; 00135 } 00136 00137 void mbedtls_ctr_drbg_set_reseed_interval( mbedtls_ctr_drbg_context *ctx, int interval ) 00138 { 00139 ctx->reseed_interval = interval; 00140 } 00141 00142 static int block_cipher_df( unsigned char *output, 00143 const unsigned char *data, size_t data_len ) 00144 { 00145 unsigned char buf[MBEDTLS_CTR_DRBG_MAX_SEED_INPUT + MBEDTLS_CTR_DRBG_BLOCKSIZE + 16]; 00146 unsigned char tmp[MBEDTLS_CTR_DRBG_SEEDLEN]; 00147 unsigned char key[MBEDTLS_CTR_DRBG_KEYSIZE]; 00148 unsigned char chain[MBEDTLS_CTR_DRBG_BLOCKSIZE]; 00149 unsigned char *p, *iv; 00150 mbedtls_aes_context aes_ctx; 00151 00152 int i, j; 00153 size_t buf_len, use_len; 00154 00155 if( data_len > MBEDTLS_CTR_DRBG_MAX_SEED_INPUT ) 00156 return( MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG ); 00157 00158 memset( buf, 0, MBEDTLS_CTR_DRBG_MAX_SEED_INPUT + MBEDTLS_CTR_DRBG_BLOCKSIZE + 16 ); 00159 mbedtls_aes_init( &aes_ctx ); 00160 00161 /* 00162 * Construct IV (16 bytes) and S in buffer 00163 * IV = Counter (in 32-bits) padded to 16 with zeroes 00164 * S = Length input string (in 32-bits) || Length of output (in 32-bits) || 00165 * data || 0x80 00166 * (Total is padded to a multiple of 16-bytes with zeroes) 00167 */ 00168 p = buf + MBEDTLS_CTR_DRBG_BLOCKSIZE; 00169 *p++ = ( data_len >> 24 ) & 0xff; 00170 *p++ = ( data_len >> 16 ) & 0xff; 00171 *p++ = ( data_len >> 8 ) & 0xff; 00172 *p++ = ( data_len ) & 0xff; 00173 p += 3; 00174 *p++ = MBEDTLS_CTR_DRBG_SEEDLEN; 00175 memcpy( p, data, data_len ); 00176 p[data_len] = 0x80; 00177 00178 buf_len = MBEDTLS_CTR_DRBG_BLOCKSIZE + 8 + data_len + 1; 00179 00180 for( i = 0; i < MBEDTLS_CTR_DRBG_KEYSIZE; i++ ) 00181 key[i] = i; 00182 00183 mbedtls_aes_setkey_enc( &aes_ctx, key, MBEDTLS_CTR_DRBG_KEYBITS ); 00184 00185 /* 00186 * Reduce data to MBEDTLS_CTR_DRBG_SEEDLEN bytes of data 00187 */ 00188 for( j = 0; j < MBEDTLS_CTR_DRBG_SEEDLEN; j += MBEDTLS_CTR_DRBG_BLOCKSIZE ) 00189 { 00190 p = buf; 00191 memset( chain, 0, MBEDTLS_CTR_DRBG_BLOCKSIZE ); 00192 use_len = buf_len; 00193 00194 while( use_len > 0 ) 00195 { 00196 for( i = 0; i < MBEDTLS_CTR_DRBG_BLOCKSIZE; i++ ) 00197 chain[i] ^= p[i]; 00198 p += MBEDTLS_CTR_DRBG_BLOCKSIZE; 00199 use_len -= ( use_len >= MBEDTLS_CTR_DRBG_BLOCKSIZE ) ? 00200 MBEDTLS_CTR_DRBG_BLOCKSIZE : use_len; 00201 00202 mbedtls_aes_crypt_ecb( &aes_ctx, MBEDTLS_AES_ENCRYPT, chain, chain ); 00203 } 00204 00205 memcpy( tmp + j, chain, MBEDTLS_CTR_DRBG_BLOCKSIZE ); 00206 00207 /* 00208 * Update IV 00209 */ 00210 buf[3]++; 00211 } 00212 00213 /* 00214 * Do final encryption with reduced data 00215 */ 00216 mbedtls_aes_setkey_enc( &aes_ctx, tmp, MBEDTLS_CTR_DRBG_KEYBITS ); 00217 iv = tmp + MBEDTLS_CTR_DRBG_KEYSIZE; 00218 p = output; 00219 00220 for( j = 0; j < MBEDTLS_CTR_DRBG_SEEDLEN; j += MBEDTLS_CTR_DRBG_BLOCKSIZE ) 00221 { 00222 mbedtls_aes_crypt_ecb( &aes_ctx, MBEDTLS_AES_ENCRYPT, iv, iv ); 00223 memcpy( p, iv, MBEDTLS_CTR_DRBG_BLOCKSIZE ); 00224 p += MBEDTLS_CTR_DRBG_BLOCKSIZE; 00225 } 00226 00227 mbedtls_aes_free( &aes_ctx ); 00228 00229 return( 0 ); 00230 } 00231 00232 static int ctr_drbg_update_internal( mbedtls_ctr_drbg_context *ctx, 00233 const unsigned char data[MBEDTLS_CTR_DRBG_SEEDLEN] ) 00234 { 00235 unsigned char tmp[MBEDTLS_CTR_DRBG_SEEDLEN]; 00236 unsigned char *p = tmp; 00237 int i, j; 00238 00239 memset( tmp, 0, MBEDTLS_CTR_DRBG_SEEDLEN ); 00240 00241 for( j = 0; j < MBEDTLS_CTR_DRBG_SEEDLEN; j += MBEDTLS_CTR_DRBG_BLOCKSIZE ) 00242 { 00243 /* 00244 * Increase counter 00245 */ 00246 for( i = MBEDTLS_CTR_DRBG_BLOCKSIZE; i > 0; i-- ) 00247 if( ++ctx->counter [i - 1] != 0 ) 00248 break; 00249 00250 /* 00251 * Crypt counter block 00252 */ 00253 mbedtls_aes_crypt_ecb( &ctx->aes_ctx , MBEDTLS_AES_ENCRYPT, ctx->counter , p ); 00254 00255 p += MBEDTLS_CTR_DRBG_BLOCKSIZE; 00256 } 00257 00258 for( i = 0; i < MBEDTLS_CTR_DRBG_SEEDLEN; i++ ) 00259 tmp[i] ^= data[i]; 00260 00261 /* 00262 * Update key and counter 00263 */ 00264 mbedtls_aes_setkey_enc( &ctx->aes_ctx , tmp, MBEDTLS_CTR_DRBG_KEYBITS ); 00265 memcpy( ctx->counter , tmp + MBEDTLS_CTR_DRBG_KEYSIZE, MBEDTLS_CTR_DRBG_BLOCKSIZE ); 00266 00267 return( 0 ); 00268 } 00269 00270 void mbedtls_ctr_drbg_update( mbedtls_ctr_drbg_context *ctx, 00271 const unsigned char *additional, size_t add_len ) 00272 { 00273 unsigned char add_input[MBEDTLS_CTR_DRBG_SEEDLEN]; 00274 00275 if( add_len > 0 ) 00276 { 00277 /* MAX_INPUT would be more logical here, but we have to match 00278 * block_cipher_df()'s limits since we can't propagate errors */ 00279 if( add_len > MBEDTLS_CTR_DRBG_MAX_SEED_INPUT ) 00280 add_len = MBEDTLS_CTR_DRBG_MAX_SEED_INPUT; 00281 00282 block_cipher_df( add_input, additional, add_len ); 00283 ctr_drbg_update_internal( ctx, add_input ); 00284 } 00285 } 00286 00287 int mbedtls_ctr_drbg_reseed( mbedtls_ctr_drbg_context *ctx, 00288 const unsigned char *additional, size_t len ) 00289 { 00290 unsigned char seed[MBEDTLS_CTR_DRBG_MAX_SEED_INPUT]; 00291 size_t seedlen = 0; 00292 00293 if( ctx->entropy_len + len > MBEDTLS_CTR_DRBG_MAX_SEED_INPUT ) 00294 return( MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG ); 00295 00296 memset( seed, 0, MBEDTLS_CTR_DRBG_MAX_SEED_INPUT ); 00297 00298 /* 00299 * Gather entropy_len bytes of entropy to seed state 00300 */ 00301 if( 0 != ctx->f_entropy( ctx->p_entropy , seed, 00302 ctx->entropy_len ) ) 00303 { 00304 return( MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED ); 00305 } 00306 00307 seedlen += ctx->entropy_len ; 00308 00309 /* 00310 * Add additional data 00311 */ 00312 if( additional && len ) 00313 { 00314 memcpy( seed + seedlen, additional, len ); 00315 seedlen += len; 00316 } 00317 00318 /* 00319 * Reduce to 384 bits 00320 */ 00321 block_cipher_df( seed, seed, seedlen ); 00322 00323 /* 00324 * Update state 00325 */ 00326 ctr_drbg_update_internal( ctx, seed ); 00327 ctx->reseed_counter = 1; 00328 00329 return( 0 ); 00330 } 00331 00332 int mbedtls_ctr_drbg_random_with_add( void *p_rng, 00333 unsigned char *output, size_t output_len, 00334 const unsigned char *additional, size_t add_len ) 00335 { 00336 int ret = 0; 00337 mbedtls_ctr_drbg_context *ctx = (mbedtls_ctr_drbg_context *) p_rng; 00338 unsigned char add_input[MBEDTLS_CTR_DRBG_SEEDLEN]; 00339 unsigned char *p = output; 00340 unsigned char tmp[MBEDTLS_CTR_DRBG_BLOCKSIZE]; 00341 int i; 00342 size_t use_len; 00343 00344 if( output_len > MBEDTLS_CTR_DRBG_MAX_REQUEST ) 00345 return( MBEDTLS_ERR_CTR_DRBG_REQUEST_TOO_BIG ); 00346 00347 if( add_len > MBEDTLS_CTR_DRBG_MAX_INPUT ) 00348 return( MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG ); 00349 00350 memset( add_input, 0, MBEDTLS_CTR_DRBG_SEEDLEN ); 00351 00352 if( ctx->reseed_counter > ctx->reseed_interval || 00353 ctx->prediction_resistance ) 00354 { 00355 if( ( ret = mbedtls_ctr_drbg_reseed( ctx, additional, add_len ) ) != 0 ) 00356 return( ret ); 00357 00358 add_len = 0; 00359 } 00360 00361 if( add_len > 0 ) 00362 { 00363 block_cipher_df( add_input, additional, add_len ); 00364 ctr_drbg_update_internal( ctx, add_input ); 00365 } 00366 00367 while( output_len > 0 ) 00368 { 00369 /* 00370 * Increase counter 00371 */ 00372 for( i = MBEDTLS_CTR_DRBG_BLOCKSIZE; i > 0; i-- ) 00373 if( ++ctx->counter [i - 1] != 0 ) 00374 break; 00375 00376 /* 00377 * Crypt counter block 00378 */ 00379 mbedtls_aes_crypt_ecb( &ctx->aes_ctx , MBEDTLS_AES_ENCRYPT, ctx->counter , tmp ); 00380 00381 use_len = ( output_len > MBEDTLS_CTR_DRBG_BLOCKSIZE ) ? MBEDTLS_CTR_DRBG_BLOCKSIZE : 00382 output_len; 00383 /* 00384 * Copy random block to destination 00385 */ 00386 memcpy( p, tmp, use_len ); 00387 p += use_len; 00388 output_len -= use_len; 00389 } 00390 00391 ctr_drbg_update_internal( ctx, add_input ); 00392 00393 ctx->reseed_counter ++; 00394 00395 return( 0 ); 00396 } 00397 00398 int mbedtls_ctr_drbg_random( void *p_rng, unsigned char *output, size_t output_len ) 00399 { 00400 int ret; 00401 mbedtls_ctr_drbg_context *ctx = (mbedtls_ctr_drbg_context *) p_rng; 00402 00403 #if defined(MBEDTLS_THREADING_C) 00404 if( ( ret = mbedtls_mutex_lock( &ctx->mutex ) ) != 0 ) 00405 return( ret ); 00406 #endif 00407 00408 ret = mbedtls_ctr_drbg_random_with_add( ctx, output, output_len, NULL, 0 ); 00409 00410 #if defined(MBEDTLS_THREADING_C) 00411 if( mbedtls_mutex_unlock( &ctx->mutex ) != 0 ) 00412 return( MBEDTLS_ERR_THREADING_MUTEX_ERROR ); 00413 #endif 00414 00415 return( ret ); 00416 } 00417 00418 #if defined(MBEDTLS_FS_IO) 00419 int mbedtls_ctr_drbg_write_seed_file( mbedtls_ctr_drbg_context *ctx, const char *path ) 00420 { 00421 int ret = MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR; 00422 FILE *f; 00423 unsigned char buf[ MBEDTLS_CTR_DRBG_MAX_INPUT ]; 00424 00425 if( ( f = fopen( path, "wb" ) ) == NULL ) 00426 return( MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR ); 00427 00428 if( ( ret = mbedtls_ctr_drbg_random( ctx, buf, MBEDTLS_CTR_DRBG_MAX_INPUT ) ) != 0 ) 00429 goto exit; 00430 00431 if( fwrite( buf, 1, MBEDTLS_CTR_DRBG_MAX_INPUT, f ) != MBEDTLS_CTR_DRBG_MAX_INPUT ) 00432 { 00433 ret = MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR; 00434 goto exit; 00435 } 00436 00437 ret = 0; 00438 00439 exit: 00440 fclose( f ); 00441 return( ret ); 00442 } 00443 00444 int mbedtls_ctr_drbg_update_seed_file( mbedtls_ctr_drbg_context *ctx, const char *path ) 00445 { 00446 FILE *f; 00447 size_t n; 00448 unsigned char buf[ MBEDTLS_CTR_DRBG_MAX_INPUT ]; 00449 00450 if( ( f = fopen( path, "rb" ) ) == NULL ) 00451 return( MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR ); 00452 00453 fseek( f, 0, SEEK_END ); 00454 n = (size_t) ftell( f ); 00455 fseek( f, 0, SEEK_SET ); 00456 00457 if( n > MBEDTLS_CTR_DRBG_MAX_INPUT ) 00458 { 00459 fclose( f ); 00460 return( MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG ); 00461 } 00462 00463 if( fread( buf, 1, n, f ) != n ) 00464 { 00465 fclose( f ); 00466 return( MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR ); 00467 } 00468 00469 fclose( f ); 00470 00471 mbedtls_ctr_drbg_update( ctx, buf, n ); 00472 00473 return( mbedtls_ctr_drbg_write_seed_file( ctx, path ) ); 00474 } 00475 #endif /* MBEDTLS_FS_IO */ 00476 00477 #if defined(MBEDTLS_SELF_TEST) 00478 00479 static const unsigned char entropy_source_pr[96] = 00480 { 0xc1, 0x80, 0x81, 0xa6, 0x5d, 0x44, 0x02, 0x16, 00481 0x19, 0xb3, 0xf1, 0x80, 0xb1, 0xc9, 0x20, 0x02, 00482 0x6a, 0x54, 0x6f, 0x0c, 0x70, 0x81, 0x49, 0x8b, 00483 0x6e, 0xa6, 0x62, 0x52, 0x6d, 0x51, 0xb1, 0xcb, 00484 0x58, 0x3b, 0xfa, 0xd5, 0x37, 0x5f, 0xfb, 0xc9, 00485 0xff, 0x46, 0xd2, 0x19, 0xc7, 0x22, 0x3e, 0x95, 00486 0x45, 0x9d, 0x82, 0xe1, 0xe7, 0x22, 0x9f, 0x63, 00487 0x31, 0x69, 0xd2, 0x6b, 0x57, 0x47, 0x4f, 0xa3, 00488 0x37, 0xc9, 0x98, 0x1c, 0x0b, 0xfb, 0x91, 0x31, 00489 0x4d, 0x55, 0xb9, 0xe9, 0x1c, 0x5a, 0x5e, 0xe4, 00490 0x93, 0x92, 0xcf, 0xc5, 0x23, 0x12, 0xd5, 0x56, 00491 0x2c, 0x4a, 0x6e, 0xff, 0xdc, 0x10, 0xd0, 0x68 }; 00492 00493 static const unsigned char entropy_source_nopr[64] = 00494 { 0x5a, 0x19, 0x4d, 0x5e, 0x2b, 0x31, 0x58, 0x14, 00495 0x54, 0xde, 0xf6, 0x75, 0xfb, 0x79, 0x58, 0xfe, 00496 0xc7, 0xdb, 0x87, 0x3e, 0x56, 0x89, 0xfc, 0x9d, 00497 0x03, 0x21, 0x7c, 0x68, 0xd8, 0x03, 0x38, 0x20, 00498 0xf9, 0xe6, 0x5e, 0x04, 0xd8, 0x56, 0xf3, 0xa9, 00499 0xc4, 0x4a, 0x4c, 0xbd, 0xc1, 0xd0, 0x08, 0x46, 00500 0xf5, 0x98, 0x3d, 0x77, 0x1c, 0x1b, 0x13, 0x7e, 00501 0x4e, 0x0f, 0x9d, 0x8e, 0xf4, 0x09, 0xf9, 0x2e }; 00502 00503 static const unsigned char nonce_pers_pr[16] = 00504 { 0xd2, 0x54, 0xfc, 0xff, 0x02, 0x1e, 0x69, 0xd2, 00505 0x29, 0xc9, 0xcf, 0xad, 0x85, 0xfa, 0x48, 0x6c }; 00506 00507 static const unsigned char nonce_pers_nopr[16] = 00508 { 0x1b, 0x54, 0xb8, 0xff, 0x06, 0x42, 0xbf, 0xf5, 00509 0x21, 0xf1, 0x5c, 0x1c, 0x0b, 0x66, 0x5f, 0x3f }; 00510 00511 static const unsigned char result_pr[16] = 00512 { 0x34, 0x01, 0x16, 0x56, 0xb4, 0x29, 0x00, 0x8f, 00513 0x35, 0x63, 0xec, 0xb5, 0xf2, 0x59, 0x07, 0x23 }; 00514 00515 static const unsigned char result_nopr[16] = 00516 { 0xa0, 0x54, 0x30, 0x3d, 0x8a, 0x7e, 0xa9, 0x88, 00517 0x9d, 0x90, 0x3e, 0x07, 0x7c, 0x6f, 0x21, 0x8f }; 00518 00519 static size_t test_offset; 00520 static int ctr_drbg_self_test_entropy( void *data, unsigned char *buf, 00521 size_t len ) 00522 { 00523 const unsigned char *p = data; 00524 memcpy( buf, p + test_offset, len ); 00525 test_offset += len; 00526 return( 0 ); 00527 } 00528 00529 #define CHK( c ) if( (c) != 0 ) \ 00530 { \ 00531 if( verbose != 0 ) \ 00532 mbedtls_printf( "failed\n" ); \ 00533 return( 1 ); \ 00534 } 00535 00536 /* 00537 * Checkup routine 00538 */ 00539 int mbedtls_ctr_drbg_self_test( int verbose ) 00540 { 00541 mbedtls_ctr_drbg_context ctx; 00542 unsigned char buf[16]; 00543 00544 mbedtls_ctr_drbg_init( &ctx ); 00545 00546 /* 00547 * Based on a NIST CTR_DRBG test vector (PR = True) 00548 */ 00549 if( verbose != 0 ) 00550 mbedtls_printf( " CTR_DRBG (PR = TRUE) : " ); 00551 00552 test_offset = 0; 00553 CHK( mbedtls_ctr_drbg_seed_entropy_len( &ctx, ctr_drbg_self_test_entropy, 00554 (void *) entropy_source_pr, nonce_pers_pr, 16, 32 ) ); 00555 mbedtls_ctr_drbg_set_prediction_resistance( &ctx, MBEDTLS_CTR_DRBG_PR_ON ); 00556 CHK( mbedtls_ctr_drbg_random( &ctx, buf, MBEDTLS_CTR_DRBG_BLOCKSIZE ) ); 00557 CHK( mbedtls_ctr_drbg_random( &ctx, buf, MBEDTLS_CTR_DRBG_BLOCKSIZE ) ); 00558 CHK( memcmp( buf, result_pr, MBEDTLS_CTR_DRBG_BLOCKSIZE ) ); 00559 00560 mbedtls_ctr_drbg_free( &ctx ); 00561 00562 if( verbose != 0 ) 00563 mbedtls_printf( "passed\n" ); 00564 00565 /* 00566 * Based on a NIST CTR_DRBG test vector (PR = FALSE) 00567 */ 00568 if( verbose != 0 ) 00569 mbedtls_printf( " CTR_DRBG (PR = FALSE): " ); 00570 00571 mbedtls_ctr_drbg_init( &ctx ); 00572 00573 test_offset = 0; 00574 CHK( mbedtls_ctr_drbg_seed_entropy_len( &ctx, ctr_drbg_self_test_entropy, 00575 (void *) entropy_source_nopr, nonce_pers_nopr, 16, 32 ) ); 00576 CHK( mbedtls_ctr_drbg_random( &ctx, buf, 16 ) ); 00577 CHK( mbedtls_ctr_drbg_reseed( &ctx, NULL, 0 ) ); 00578 CHK( mbedtls_ctr_drbg_random( &ctx, buf, 16 ) ); 00579 CHK( memcmp( buf, result_nopr, 16 ) ); 00580 00581 mbedtls_ctr_drbg_free( &ctx ); 00582 00583 if( verbose != 0 ) 00584 mbedtls_printf( "passed\n" ); 00585 00586 if( verbose != 0 ) 00587 mbedtls_printf( "\n" ); 00588 00589 return( 0 ); 00590 } 00591 #endif /* MBEDTLS_SELF_TEST */ 00592 00593 #endif /* MBEDTLS_CTR_DRBG_C */
Generated on Tue Jul 12 2022 12:52:42 by 1.7.2