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