Marco Zecchini
/
Example_RTOS
Rtos API example
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 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 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 > MBEDTLS_CTR_DRBG_MAX_SEED_INPUT || 00294 len > MBEDTLS_CTR_DRBG_MAX_SEED_INPUT - ctx->entropy_len ) 00295 return( MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG ); 00296 00297 memset( seed, 0, MBEDTLS_CTR_DRBG_MAX_SEED_INPUT ); 00298 00299 /* 00300 * Gather entropy_len bytes of entropy to seed state 00301 */ 00302 if( 0 != ctx->f_entropy( ctx->p_entropy , seed, 00303 ctx->entropy_len ) ) 00304 { 00305 return( MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED ); 00306 } 00307 00308 seedlen += ctx->entropy_len ; 00309 00310 /* 00311 * Add additional data 00312 */ 00313 if( additional && len ) 00314 { 00315 memcpy( seed + seedlen, additional, len ); 00316 seedlen += len; 00317 } 00318 00319 /* 00320 * Reduce to 384 bits 00321 */ 00322 block_cipher_df( seed, seed, seedlen ); 00323 00324 /* 00325 * Update state 00326 */ 00327 ctr_drbg_update_internal( ctx, seed ); 00328 ctx->reseed_counter = 1; 00329 00330 return( 0 ); 00331 } 00332 00333 int mbedtls_ctr_drbg_random_with_add( void *p_rng, 00334 unsigned char *output, size_t output_len, 00335 const unsigned char *additional, size_t add_len ) 00336 { 00337 int ret = 0; 00338 mbedtls_ctr_drbg_context *ctx = (mbedtls_ctr_drbg_context *) p_rng; 00339 unsigned char add_input[MBEDTLS_CTR_DRBG_SEEDLEN]; 00340 unsigned char *p = output; 00341 unsigned char tmp[MBEDTLS_CTR_DRBG_BLOCKSIZE]; 00342 int i; 00343 size_t use_len; 00344 00345 if( output_len > MBEDTLS_CTR_DRBG_MAX_REQUEST ) 00346 return( MBEDTLS_ERR_CTR_DRBG_REQUEST_TOO_BIG ); 00347 00348 if( add_len > MBEDTLS_CTR_DRBG_MAX_INPUT ) 00349 return( MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG ); 00350 00351 memset( add_input, 0, MBEDTLS_CTR_DRBG_SEEDLEN ); 00352 00353 if( ctx->reseed_counter > ctx->reseed_interval || 00354 ctx->prediction_resistance ) 00355 { 00356 if( ( ret = mbedtls_ctr_drbg_reseed( ctx, additional, add_len ) ) != 0 ) 00357 return( ret ); 00358 00359 add_len = 0; 00360 } 00361 00362 if( add_len > 0 ) 00363 { 00364 block_cipher_df( add_input, additional, add_len ); 00365 ctr_drbg_update_internal( ctx, add_input ); 00366 } 00367 00368 while( output_len > 0 ) 00369 { 00370 /* 00371 * Increase counter 00372 */ 00373 for( i = MBEDTLS_CTR_DRBG_BLOCKSIZE; i > 0; i-- ) 00374 if( ++ctx->counter [i - 1] != 0 ) 00375 break; 00376 00377 /* 00378 * Crypt counter block 00379 */ 00380 mbedtls_aes_crypt_ecb( &ctx->aes_ctx , MBEDTLS_AES_ENCRYPT, ctx->counter , tmp ); 00381 00382 use_len = ( output_len > MBEDTLS_CTR_DRBG_BLOCKSIZE ) ? MBEDTLS_CTR_DRBG_BLOCKSIZE : 00383 output_len; 00384 /* 00385 * Copy random block to destination 00386 */ 00387 memcpy( p, tmp, use_len ); 00388 p += use_len; 00389 output_len -= use_len; 00390 } 00391 00392 ctr_drbg_update_internal( ctx, add_input ); 00393 00394 ctx->reseed_counter ++; 00395 00396 return( 0 ); 00397 } 00398 00399 int mbedtls_ctr_drbg_random( void *p_rng, unsigned char *output, size_t output_len ) 00400 { 00401 int ret; 00402 mbedtls_ctr_drbg_context *ctx = (mbedtls_ctr_drbg_context *) p_rng; 00403 00404 #if defined(MBEDTLS_THREADING_C) 00405 if( ( ret = mbedtls_mutex_lock( &ctx->mutex ) ) != 0 ) 00406 return( ret ); 00407 #endif 00408 00409 ret = mbedtls_ctr_drbg_random_with_add( ctx, output, output_len, NULL, 0 ); 00410 00411 #if defined(MBEDTLS_THREADING_C) 00412 if( mbedtls_mutex_unlock( &ctx->mutex ) != 0 ) 00413 return( MBEDTLS_ERR_THREADING_MUTEX_ERROR ); 00414 #endif 00415 00416 return( ret ); 00417 } 00418 00419 #if defined(MBEDTLS_FS_IO) 00420 int mbedtls_ctr_drbg_write_seed_file( mbedtls_ctr_drbg_context *ctx, const char *path ) 00421 { 00422 int ret = MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR; 00423 FILE *f; 00424 unsigned char buf[ MBEDTLS_CTR_DRBG_MAX_INPUT ]; 00425 00426 if( ( f = fopen( path, "wb" ) ) == NULL ) 00427 return( MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR ); 00428 00429 if( ( ret = mbedtls_ctr_drbg_random( ctx, buf, MBEDTLS_CTR_DRBG_MAX_INPUT ) ) != 0 ) 00430 goto exit; 00431 00432 if( fwrite( buf, 1, MBEDTLS_CTR_DRBG_MAX_INPUT, f ) != MBEDTLS_CTR_DRBG_MAX_INPUT ) 00433 { 00434 ret = MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR; 00435 goto exit; 00436 } 00437 00438 ret = 0; 00439 00440 exit: 00441 fclose( f ); 00442 return( ret ); 00443 } 00444 00445 int mbedtls_ctr_drbg_update_seed_file( mbedtls_ctr_drbg_context *ctx, const char *path ) 00446 { 00447 FILE *f; 00448 size_t n; 00449 unsigned char buf[ MBEDTLS_CTR_DRBG_MAX_INPUT ]; 00450 00451 if( ( f = fopen( path, "rb" ) ) == NULL ) 00452 return( MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR ); 00453 00454 fseek( f, 0, SEEK_END ); 00455 n = (size_t) ftell( f ); 00456 fseek( f, 0, SEEK_SET ); 00457 00458 if( n > MBEDTLS_CTR_DRBG_MAX_INPUT ) 00459 { 00460 fclose( f ); 00461 return( MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG ); 00462 } 00463 00464 if( fread( buf, 1, n, f ) != n ) 00465 { 00466 fclose( f ); 00467 return( MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR ); 00468 } 00469 00470 fclose( f ); 00471 00472 mbedtls_ctr_drbg_update( ctx, buf, n ); 00473 00474 return( mbedtls_ctr_drbg_write_seed_file( ctx, path ) ); 00475 } 00476 #endif /* MBEDTLS_FS_IO */ 00477 00478 #if defined(MBEDTLS_SELF_TEST) 00479 00480 static const unsigned char entropy_source_pr[96] = 00481 { 0xc1, 0x80, 0x81, 0xa6, 0x5d, 0x44, 0x02, 0x16, 00482 0x19, 0xb3, 0xf1, 0x80, 0xb1, 0xc9, 0x20, 0x02, 00483 0x6a, 0x54, 0x6f, 0x0c, 0x70, 0x81, 0x49, 0x8b, 00484 0x6e, 0xa6, 0x62, 0x52, 0x6d, 0x51, 0xb1, 0xcb, 00485 0x58, 0x3b, 0xfa, 0xd5, 0x37, 0x5f, 0xfb, 0xc9, 00486 0xff, 0x46, 0xd2, 0x19, 0xc7, 0x22, 0x3e, 0x95, 00487 0x45, 0x9d, 0x82, 0xe1, 0xe7, 0x22, 0x9f, 0x63, 00488 0x31, 0x69, 0xd2, 0x6b, 0x57, 0x47, 0x4f, 0xa3, 00489 0x37, 0xc9, 0x98, 0x1c, 0x0b, 0xfb, 0x91, 0x31, 00490 0x4d, 0x55, 0xb9, 0xe9, 0x1c, 0x5a, 0x5e, 0xe4, 00491 0x93, 0x92, 0xcf, 0xc5, 0x23, 0x12, 0xd5, 0x56, 00492 0x2c, 0x4a, 0x6e, 0xff, 0xdc, 0x10, 0xd0, 0x68 }; 00493 00494 static const unsigned char entropy_source_nopr[64] = 00495 { 0x5a, 0x19, 0x4d, 0x5e, 0x2b, 0x31, 0x58, 0x14, 00496 0x54, 0xde, 0xf6, 0x75, 0xfb, 0x79, 0x58, 0xfe, 00497 0xc7, 0xdb, 0x87, 0x3e, 0x56, 0x89, 0xfc, 0x9d, 00498 0x03, 0x21, 0x7c, 0x68, 0xd8, 0x03, 0x38, 0x20, 00499 0xf9, 0xe6, 0x5e, 0x04, 0xd8, 0x56, 0xf3, 0xa9, 00500 0xc4, 0x4a, 0x4c, 0xbd, 0xc1, 0xd0, 0x08, 0x46, 00501 0xf5, 0x98, 0x3d, 0x77, 0x1c, 0x1b, 0x13, 0x7e, 00502 0x4e, 0x0f, 0x9d, 0x8e, 0xf4, 0x09, 0xf9, 0x2e }; 00503 00504 static const unsigned char nonce_pers_pr[16] = 00505 { 0xd2, 0x54, 0xfc, 0xff, 0x02, 0x1e, 0x69, 0xd2, 00506 0x29, 0xc9, 0xcf, 0xad, 0x85, 0xfa, 0x48, 0x6c }; 00507 00508 static const unsigned char nonce_pers_nopr[16] = 00509 { 0x1b, 0x54, 0xb8, 0xff, 0x06, 0x42, 0xbf, 0xf5, 00510 0x21, 0xf1, 0x5c, 0x1c, 0x0b, 0x66, 0x5f, 0x3f }; 00511 00512 static const unsigned char result_pr[16] = 00513 { 0x34, 0x01, 0x16, 0x56, 0xb4, 0x29, 0x00, 0x8f, 00514 0x35, 0x63, 0xec, 0xb5, 0xf2, 0x59, 0x07, 0x23 }; 00515 00516 static const unsigned char result_nopr[16] = 00517 { 0xa0, 0x54, 0x30, 0x3d, 0x8a, 0x7e, 0xa9, 0x88, 00518 0x9d, 0x90, 0x3e, 0x07, 0x7c, 0x6f, 0x21, 0x8f }; 00519 00520 static size_t test_offset; 00521 static int ctr_drbg_self_test_entropy( void *data, unsigned char *buf, 00522 size_t len ) 00523 { 00524 const unsigned char *p = data; 00525 memcpy( buf, p + test_offset, len ); 00526 test_offset += len; 00527 return( 0 ); 00528 } 00529 00530 #define CHK( c ) if( (c) != 0 ) \ 00531 { \ 00532 if( verbose != 0 ) \ 00533 mbedtls_printf( "failed\n" ); \ 00534 return( 1 ); \ 00535 } 00536 00537 /* 00538 * Checkup routine 00539 */ 00540 int mbedtls_ctr_drbg_self_test( int verbose ) 00541 { 00542 mbedtls_ctr_drbg_context ctx; 00543 unsigned char buf[16]; 00544 00545 mbedtls_ctr_drbg_init( &ctx ); 00546 00547 /* 00548 * Based on a NIST CTR_DRBG test vector (PR = True) 00549 */ 00550 if( verbose != 0 ) 00551 mbedtls_printf( " CTR_DRBG (PR = TRUE) : " ); 00552 00553 test_offset = 0; 00554 CHK( mbedtls_ctr_drbg_seed_entropy_len( &ctx, ctr_drbg_self_test_entropy, 00555 (void *) entropy_source_pr, nonce_pers_pr, 16, 32 ) ); 00556 mbedtls_ctr_drbg_set_prediction_resistance( &ctx, MBEDTLS_CTR_DRBG_PR_ON ); 00557 CHK( mbedtls_ctr_drbg_random( &ctx, buf, MBEDTLS_CTR_DRBG_BLOCKSIZE ) ); 00558 CHK( mbedtls_ctr_drbg_random( &ctx, buf, MBEDTLS_CTR_DRBG_BLOCKSIZE ) ); 00559 CHK( memcmp( buf, result_pr, MBEDTLS_CTR_DRBG_BLOCKSIZE ) ); 00560 00561 mbedtls_ctr_drbg_free( &ctx ); 00562 00563 if( verbose != 0 ) 00564 mbedtls_printf( "passed\n" ); 00565 00566 /* 00567 * Based on a NIST CTR_DRBG test vector (PR = FALSE) 00568 */ 00569 if( verbose != 0 ) 00570 mbedtls_printf( " CTR_DRBG (PR = FALSE): " ); 00571 00572 mbedtls_ctr_drbg_init( &ctx ); 00573 00574 test_offset = 0; 00575 CHK( mbedtls_ctr_drbg_seed_entropy_len( &ctx, ctr_drbg_self_test_entropy, 00576 (void *) entropy_source_nopr, nonce_pers_nopr, 16, 32 ) ); 00577 CHK( mbedtls_ctr_drbg_random( &ctx, buf, 16 ) ); 00578 CHK( mbedtls_ctr_drbg_reseed( &ctx, NULL, 0 ) ); 00579 CHK( mbedtls_ctr_drbg_random( &ctx, buf, 16 ) ); 00580 CHK( memcmp( buf, result_nopr, 16 ) ); 00581 00582 mbedtls_ctr_drbg_free( &ctx ); 00583 00584 if( verbose != 0 ) 00585 mbedtls_printf( "passed\n" ); 00586 00587 if( verbose != 0 ) 00588 mbedtls_printf( "\n" ); 00589 00590 return( 0 ); 00591 } 00592 #endif /* MBEDTLS_SELF_TEST */ 00593 00594 #endif /* MBEDTLS_CTR_DRBG_C */
Generated on Sun Jul 17 2022 08:25:21 by 1.7.2