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