RTC auf true

Committer:
kevman
Date:
Wed Mar 13 11:03:24 2019 +0000
Revision:
2:7aab896b1a3b
Parent:
0:38ceb79fef03
2019-03-13

Who changed what in which revision?

UserRevisionLine numberNew contents of line
kevman 0:38ceb79fef03 1 /*
kevman 0:38ceb79fef03 2 * CTR_DRBG implementation based on AES-256 (NIST SP 800-90)
kevman 0:38ceb79fef03 3 *
kevman 0:38ceb79fef03 4 * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
kevman 0:38ceb79fef03 5 * SPDX-License-Identifier: Apache-2.0
kevman 0:38ceb79fef03 6 *
kevman 0:38ceb79fef03 7 * Licensed under the Apache License, Version 2.0 (the "License"); you may
kevman 0:38ceb79fef03 8 * not use this file except in compliance with the License.
kevman 0:38ceb79fef03 9 * You may obtain a copy of the License at
kevman 0:38ceb79fef03 10 *
kevman 0:38ceb79fef03 11 * http://www.apache.org/licenses/LICENSE-2.0
kevman 0:38ceb79fef03 12 *
kevman 0:38ceb79fef03 13 * Unless required by applicable law or agreed to in writing, software
kevman 0:38ceb79fef03 14 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
kevman 0:38ceb79fef03 15 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
kevman 0:38ceb79fef03 16 * See the License for the specific language governing permissions and
kevman 0:38ceb79fef03 17 * limitations under the License.
kevman 0:38ceb79fef03 18 *
kevman 0:38ceb79fef03 19 * This file is part of mbed TLS (https://tls.mbed.org)
kevman 0:38ceb79fef03 20 */
kevman 0:38ceb79fef03 21 /*
kevman 0:38ceb79fef03 22 * The NIST SP 800-90 DRBGs are described in the following publication.
kevman 0:38ceb79fef03 23 *
kevman 0:38ceb79fef03 24 * http://csrc.nist.gov/publications/nistpubs/800-90/SP800-90revised_March2007.pdf
kevman 0:38ceb79fef03 25 */
kevman 0:38ceb79fef03 26
kevman 0:38ceb79fef03 27 #if !defined(MBEDTLS_CONFIG_FILE)
kevman 0:38ceb79fef03 28 #include "mbedtls/config.h"
kevman 0:38ceb79fef03 29 #else
kevman 0:38ceb79fef03 30 #include MBEDTLS_CONFIG_FILE
kevman 0:38ceb79fef03 31 #endif
kevman 0:38ceb79fef03 32
kevman 0:38ceb79fef03 33 #if defined(MBEDTLS_CTR_DRBG_C)
kevman 0:38ceb79fef03 34
kevman 0:38ceb79fef03 35 #include "mbedtls/ctr_drbg.h"
kevman 0:38ceb79fef03 36 #include "mbedtls/platform_util.h"
kevman 0:38ceb79fef03 37
kevman 0:38ceb79fef03 38 #include <string.h>
kevman 0:38ceb79fef03 39
kevman 0:38ceb79fef03 40 #if defined(MBEDTLS_FS_IO)
kevman 0:38ceb79fef03 41 #include <stdio.h>
kevman 0:38ceb79fef03 42 #endif
kevman 0:38ceb79fef03 43
kevman 0:38ceb79fef03 44 #if defined(MBEDTLS_SELF_TEST)
kevman 0:38ceb79fef03 45 #if defined(MBEDTLS_PLATFORM_C)
kevman 0:38ceb79fef03 46 #include "mbedtls/platform.h"
kevman 0:38ceb79fef03 47 #else
kevman 0:38ceb79fef03 48 #include <stdio.h>
kevman 0:38ceb79fef03 49 #define mbedtls_printf printf
kevman 0:38ceb79fef03 50 #endif /* MBEDTLS_PLATFORM_C */
kevman 0:38ceb79fef03 51 #endif /* MBEDTLS_SELF_TEST */
kevman 0:38ceb79fef03 52
kevman 0:38ceb79fef03 53 /*
kevman 0:38ceb79fef03 54 * CTR_DRBG context initialization
kevman 0:38ceb79fef03 55 */
kevman 0:38ceb79fef03 56 void mbedtls_ctr_drbg_init( mbedtls_ctr_drbg_context *ctx )
kevman 0:38ceb79fef03 57 {
kevman 0:38ceb79fef03 58 memset( ctx, 0, sizeof( mbedtls_ctr_drbg_context ) );
kevman 0:38ceb79fef03 59
kevman 0:38ceb79fef03 60 #if defined(MBEDTLS_THREADING_C)
kevman 0:38ceb79fef03 61 mbedtls_mutex_init( &ctx->mutex );
kevman 0:38ceb79fef03 62 #endif
kevman 0:38ceb79fef03 63 }
kevman 0:38ceb79fef03 64
kevman 0:38ceb79fef03 65 /*
kevman 0:38ceb79fef03 66 * Non-public function wrapped by mbedtls_ctr_drbg_seed(). Necessary to allow
kevman 0:38ceb79fef03 67 * NIST tests to succeed (which require known length fixed entropy)
kevman 0:38ceb79fef03 68 */
kevman 0:38ceb79fef03 69 int mbedtls_ctr_drbg_seed_entropy_len(
kevman 0:38ceb79fef03 70 mbedtls_ctr_drbg_context *ctx,
kevman 0:38ceb79fef03 71 int (*f_entropy)(void *, unsigned char *, size_t),
kevman 0:38ceb79fef03 72 void *p_entropy,
kevman 0:38ceb79fef03 73 const unsigned char *custom,
kevman 0:38ceb79fef03 74 size_t len,
kevman 0:38ceb79fef03 75 size_t entropy_len )
kevman 0:38ceb79fef03 76 {
kevman 0:38ceb79fef03 77 int ret;
kevman 0:38ceb79fef03 78 unsigned char key[MBEDTLS_CTR_DRBG_KEYSIZE];
kevman 0:38ceb79fef03 79
kevman 0:38ceb79fef03 80 memset( key, 0, MBEDTLS_CTR_DRBG_KEYSIZE );
kevman 0:38ceb79fef03 81
kevman 0:38ceb79fef03 82 mbedtls_aes_init( &ctx->aes_ctx );
kevman 0:38ceb79fef03 83
kevman 0:38ceb79fef03 84 ctx->f_entropy = f_entropy;
kevman 0:38ceb79fef03 85 ctx->p_entropy = p_entropy;
kevman 0:38ceb79fef03 86
kevman 0:38ceb79fef03 87 ctx->entropy_len = entropy_len;
kevman 0:38ceb79fef03 88 ctx->reseed_interval = MBEDTLS_CTR_DRBG_RESEED_INTERVAL;
kevman 0:38ceb79fef03 89
kevman 0:38ceb79fef03 90 /*
kevman 0:38ceb79fef03 91 * Initialize with an empty key
kevman 0:38ceb79fef03 92 */
kevman 0:38ceb79fef03 93 if( ( ret = mbedtls_aes_setkey_enc( &ctx->aes_ctx, key, MBEDTLS_CTR_DRBG_KEYBITS ) ) != 0 )
kevman 0:38ceb79fef03 94 {
kevman 0:38ceb79fef03 95 return( ret );
kevman 0:38ceb79fef03 96 }
kevman 0:38ceb79fef03 97
kevman 0:38ceb79fef03 98 if( ( ret = mbedtls_ctr_drbg_reseed( ctx, custom, len ) ) != 0 )
kevman 0:38ceb79fef03 99 {
kevman 0:38ceb79fef03 100 return( ret );
kevman 0:38ceb79fef03 101 }
kevman 0:38ceb79fef03 102 return( 0 );
kevman 0:38ceb79fef03 103 }
kevman 0:38ceb79fef03 104
kevman 0:38ceb79fef03 105 int mbedtls_ctr_drbg_seed( mbedtls_ctr_drbg_context *ctx,
kevman 0:38ceb79fef03 106 int (*f_entropy)(void *, unsigned char *, size_t),
kevman 0:38ceb79fef03 107 void *p_entropy,
kevman 0:38ceb79fef03 108 const unsigned char *custom,
kevman 0:38ceb79fef03 109 size_t len )
kevman 0:38ceb79fef03 110 {
kevman 0:38ceb79fef03 111 return( mbedtls_ctr_drbg_seed_entropy_len( ctx, f_entropy, p_entropy, custom, len,
kevman 0:38ceb79fef03 112 MBEDTLS_CTR_DRBG_ENTROPY_LEN ) );
kevman 0:38ceb79fef03 113 }
kevman 0:38ceb79fef03 114
kevman 0:38ceb79fef03 115 void mbedtls_ctr_drbg_free( mbedtls_ctr_drbg_context *ctx )
kevman 0:38ceb79fef03 116 {
kevman 0:38ceb79fef03 117 if( ctx == NULL )
kevman 0:38ceb79fef03 118 return;
kevman 0:38ceb79fef03 119
kevman 0:38ceb79fef03 120 #if defined(MBEDTLS_THREADING_C)
kevman 0:38ceb79fef03 121 mbedtls_mutex_free( &ctx->mutex );
kevman 0:38ceb79fef03 122 #endif
kevman 0:38ceb79fef03 123 mbedtls_aes_free( &ctx->aes_ctx );
kevman 0:38ceb79fef03 124 mbedtls_platform_zeroize( ctx, sizeof( mbedtls_ctr_drbg_context ) );
kevman 0:38ceb79fef03 125 }
kevman 0:38ceb79fef03 126
kevman 0:38ceb79fef03 127 void mbedtls_ctr_drbg_set_prediction_resistance( mbedtls_ctr_drbg_context *ctx, int resistance )
kevman 0:38ceb79fef03 128 {
kevman 0:38ceb79fef03 129 ctx->prediction_resistance = resistance;
kevman 0:38ceb79fef03 130 }
kevman 0:38ceb79fef03 131
kevman 0:38ceb79fef03 132 void mbedtls_ctr_drbg_set_entropy_len( mbedtls_ctr_drbg_context *ctx, size_t len )
kevman 0:38ceb79fef03 133 {
kevman 0:38ceb79fef03 134 ctx->entropy_len = len;
kevman 0:38ceb79fef03 135 }
kevman 0:38ceb79fef03 136
kevman 0:38ceb79fef03 137 void mbedtls_ctr_drbg_set_reseed_interval( mbedtls_ctr_drbg_context *ctx, int interval )
kevman 0:38ceb79fef03 138 {
kevman 0:38ceb79fef03 139 ctx->reseed_interval = interval;
kevman 0:38ceb79fef03 140 }
kevman 0:38ceb79fef03 141
kevman 0:38ceb79fef03 142 static int block_cipher_df( unsigned char *output,
kevman 0:38ceb79fef03 143 const unsigned char *data, size_t data_len )
kevman 0:38ceb79fef03 144 {
kevman 0:38ceb79fef03 145 unsigned char buf[MBEDTLS_CTR_DRBG_MAX_SEED_INPUT + MBEDTLS_CTR_DRBG_BLOCKSIZE + 16];
kevman 0:38ceb79fef03 146 unsigned char tmp[MBEDTLS_CTR_DRBG_SEEDLEN];
kevman 0:38ceb79fef03 147 unsigned char key[MBEDTLS_CTR_DRBG_KEYSIZE];
kevman 0:38ceb79fef03 148 unsigned char chain[MBEDTLS_CTR_DRBG_BLOCKSIZE];
kevman 0:38ceb79fef03 149 unsigned char *p, *iv;
kevman 0:38ceb79fef03 150 mbedtls_aes_context aes_ctx;
kevman 0:38ceb79fef03 151 int ret = 0;
kevman 0:38ceb79fef03 152
kevman 0:38ceb79fef03 153 int i, j;
kevman 0:38ceb79fef03 154 size_t buf_len, use_len;
kevman 0:38ceb79fef03 155
kevman 0:38ceb79fef03 156 if( data_len > MBEDTLS_CTR_DRBG_MAX_SEED_INPUT )
kevman 0:38ceb79fef03 157 return( MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG );
kevman 0:38ceb79fef03 158
kevman 0:38ceb79fef03 159 memset( buf, 0, MBEDTLS_CTR_DRBG_MAX_SEED_INPUT + MBEDTLS_CTR_DRBG_BLOCKSIZE + 16 );
kevman 0:38ceb79fef03 160 mbedtls_aes_init( &aes_ctx );
kevman 0:38ceb79fef03 161
kevman 0:38ceb79fef03 162 /*
kevman 0:38ceb79fef03 163 * Construct IV (16 bytes) and S in buffer
kevman 0:38ceb79fef03 164 * IV = Counter (in 32-bits) padded to 16 with zeroes
kevman 0:38ceb79fef03 165 * S = Length input string (in 32-bits) || Length of output (in 32-bits) ||
kevman 0:38ceb79fef03 166 * data || 0x80
kevman 0:38ceb79fef03 167 * (Total is padded to a multiple of 16-bytes with zeroes)
kevman 0:38ceb79fef03 168 */
kevman 0:38ceb79fef03 169 p = buf + MBEDTLS_CTR_DRBG_BLOCKSIZE;
kevman 0:38ceb79fef03 170 *p++ = ( data_len >> 24 ) & 0xff;
kevman 0:38ceb79fef03 171 *p++ = ( data_len >> 16 ) & 0xff;
kevman 0:38ceb79fef03 172 *p++ = ( data_len >> 8 ) & 0xff;
kevman 0:38ceb79fef03 173 *p++ = ( data_len ) & 0xff;
kevman 0:38ceb79fef03 174 p += 3;
kevman 0:38ceb79fef03 175 *p++ = MBEDTLS_CTR_DRBG_SEEDLEN;
kevman 0:38ceb79fef03 176 memcpy( p, data, data_len );
kevman 0:38ceb79fef03 177 p[data_len] = 0x80;
kevman 0:38ceb79fef03 178
kevman 0:38ceb79fef03 179 buf_len = MBEDTLS_CTR_DRBG_BLOCKSIZE + 8 + data_len + 1;
kevman 0:38ceb79fef03 180
kevman 0:38ceb79fef03 181 for( i = 0; i < MBEDTLS_CTR_DRBG_KEYSIZE; i++ )
kevman 0:38ceb79fef03 182 key[i] = i;
kevman 0:38ceb79fef03 183
kevman 0:38ceb79fef03 184 if( ( ret = mbedtls_aes_setkey_enc( &aes_ctx, key, MBEDTLS_CTR_DRBG_KEYBITS ) ) != 0 )
kevman 0:38ceb79fef03 185 {
kevman 0:38ceb79fef03 186 goto exit;
kevman 0:38ceb79fef03 187 }
kevman 0:38ceb79fef03 188
kevman 0:38ceb79fef03 189 /*
kevman 0:38ceb79fef03 190 * Reduce data to MBEDTLS_CTR_DRBG_SEEDLEN bytes of data
kevman 0:38ceb79fef03 191 */
kevman 0:38ceb79fef03 192 for( j = 0; j < MBEDTLS_CTR_DRBG_SEEDLEN; j += MBEDTLS_CTR_DRBG_BLOCKSIZE )
kevman 0:38ceb79fef03 193 {
kevman 0:38ceb79fef03 194 p = buf;
kevman 0:38ceb79fef03 195 memset( chain, 0, MBEDTLS_CTR_DRBG_BLOCKSIZE );
kevman 0:38ceb79fef03 196 use_len = buf_len;
kevman 0:38ceb79fef03 197
kevman 0:38ceb79fef03 198 while( use_len > 0 )
kevman 0:38ceb79fef03 199 {
kevman 0:38ceb79fef03 200 for( i = 0; i < MBEDTLS_CTR_DRBG_BLOCKSIZE; i++ )
kevman 0:38ceb79fef03 201 chain[i] ^= p[i];
kevman 0:38ceb79fef03 202 p += MBEDTLS_CTR_DRBG_BLOCKSIZE;
kevman 0:38ceb79fef03 203 use_len -= ( use_len >= MBEDTLS_CTR_DRBG_BLOCKSIZE ) ?
kevman 0:38ceb79fef03 204 MBEDTLS_CTR_DRBG_BLOCKSIZE : use_len;
kevman 0:38ceb79fef03 205
kevman 0:38ceb79fef03 206 if( ( ret = mbedtls_aes_crypt_ecb( &aes_ctx, MBEDTLS_AES_ENCRYPT, chain, chain ) ) != 0 )
kevman 0:38ceb79fef03 207 {
kevman 0:38ceb79fef03 208 goto exit;
kevman 0:38ceb79fef03 209 }
kevman 0:38ceb79fef03 210 }
kevman 0:38ceb79fef03 211
kevman 0:38ceb79fef03 212 memcpy( tmp + j, chain, MBEDTLS_CTR_DRBG_BLOCKSIZE );
kevman 0:38ceb79fef03 213
kevman 0:38ceb79fef03 214 /*
kevman 0:38ceb79fef03 215 * Update IV
kevman 0:38ceb79fef03 216 */
kevman 0:38ceb79fef03 217 buf[3]++;
kevman 0:38ceb79fef03 218 }
kevman 0:38ceb79fef03 219
kevman 0:38ceb79fef03 220 /*
kevman 0:38ceb79fef03 221 * Do final encryption with reduced data
kevman 0:38ceb79fef03 222 */
kevman 0:38ceb79fef03 223 if( ( ret = mbedtls_aes_setkey_enc( &aes_ctx, tmp, MBEDTLS_CTR_DRBG_KEYBITS ) ) != 0 )
kevman 0:38ceb79fef03 224 {
kevman 0:38ceb79fef03 225 goto exit;
kevman 0:38ceb79fef03 226 }
kevman 0:38ceb79fef03 227 iv = tmp + MBEDTLS_CTR_DRBG_KEYSIZE;
kevman 0:38ceb79fef03 228 p = output;
kevman 0:38ceb79fef03 229
kevman 0:38ceb79fef03 230 for( j = 0; j < MBEDTLS_CTR_DRBG_SEEDLEN; j += MBEDTLS_CTR_DRBG_BLOCKSIZE )
kevman 0:38ceb79fef03 231 {
kevman 0:38ceb79fef03 232 if( ( ret = mbedtls_aes_crypt_ecb( &aes_ctx, MBEDTLS_AES_ENCRYPT, iv, iv ) ) != 0 )
kevman 0:38ceb79fef03 233 {
kevman 0:38ceb79fef03 234 goto exit;
kevman 0:38ceb79fef03 235 }
kevman 0:38ceb79fef03 236 memcpy( p, iv, MBEDTLS_CTR_DRBG_BLOCKSIZE );
kevman 0:38ceb79fef03 237 p += MBEDTLS_CTR_DRBG_BLOCKSIZE;
kevman 0:38ceb79fef03 238 }
kevman 0:38ceb79fef03 239 exit:
kevman 0:38ceb79fef03 240 mbedtls_aes_free( &aes_ctx );
kevman 0:38ceb79fef03 241 /*
kevman 0:38ceb79fef03 242 * tidy up the stack
kevman 0:38ceb79fef03 243 */
kevman 0:38ceb79fef03 244 mbedtls_platform_zeroize( buf, sizeof( buf ) );
kevman 0:38ceb79fef03 245 mbedtls_platform_zeroize( tmp, sizeof( tmp ) );
kevman 0:38ceb79fef03 246 mbedtls_platform_zeroize( key, sizeof( key ) );
kevman 0:38ceb79fef03 247 mbedtls_platform_zeroize( chain, sizeof( chain ) );
kevman 0:38ceb79fef03 248 if( 0 != ret )
kevman 0:38ceb79fef03 249 {
kevman 0:38ceb79fef03 250 /*
kevman 0:38ceb79fef03 251 * wipe partial seed from memory
kevman 0:38ceb79fef03 252 */
kevman 0:38ceb79fef03 253 mbedtls_platform_zeroize( output, MBEDTLS_CTR_DRBG_SEEDLEN );
kevman 0:38ceb79fef03 254 }
kevman 0:38ceb79fef03 255
kevman 0:38ceb79fef03 256 return( ret );
kevman 0:38ceb79fef03 257 }
kevman 0:38ceb79fef03 258
kevman 0:38ceb79fef03 259 static int ctr_drbg_update_internal( mbedtls_ctr_drbg_context *ctx,
kevman 0:38ceb79fef03 260 const unsigned char data[MBEDTLS_CTR_DRBG_SEEDLEN] )
kevman 0:38ceb79fef03 261 {
kevman 0:38ceb79fef03 262 unsigned char tmp[MBEDTLS_CTR_DRBG_SEEDLEN];
kevman 0:38ceb79fef03 263 unsigned char *p = tmp;
kevman 0:38ceb79fef03 264 int i, j;
kevman 0:38ceb79fef03 265 int ret = 0;
kevman 0:38ceb79fef03 266
kevman 0:38ceb79fef03 267 memset( tmp, 0, MBEDTLS_CTR_DRBG_SEEDLEN );
kevman 0:38ceb79fef03 268
kevman 0:38ceb79fef03 269 for( j = 0; j < MBEDTLS_CTR_DRBG_SEEDLEN; j += MBEDTLS_CTR_DRBG_BLOCKSIZE )
kevman 0:38ceb79fef03 270 {
kevman 0:38ceb79fef03 271 /*
kevman 0:38ceb79fef03 272 * Increase counter
kevman 0:38ceb79fef03 273 */
kevman 0:38ceb79fef03 274 for( i = MBEDTLS_CTR_DRBG_BLOCKSIZE; i > 0; i-- )
kevman 0:38ceb79fef03 275 if( ++ctx->counter[i - 1] != 0 )
kevman 0:38ceb79fef03 276 break;
kevman 0:38ceb79fef03 277
kevman 0:38ceb79fef03 278 /*
kevman 0:38ceb79fef03 279 * Crypt counter block
kevman 0:38ceb79fef03 280 */
kevman 0:38ceb79fef03 281 if( ( ret = mbedtls_aes_crypt_ecb( &ctx->aes_ctx, MBEDTLS_AES_ENCRYPT, ctx->counter, p ) ) != 0 )
kevman 0:38ceb79fef03 282 {
kevman 0:38ceb79fef03 283 return( ret );
kevman 0:38ceb79fef03 284 }
kevman 0:38ceb79fef03 285
kevman 0:38ceb79fef03 286 p += MBEDTLS_CTR_DRBG_BLOCKSIZE;
kevman 0:38ceb79fef03 287 }
kevman 0:38ceb79fef03 288
kevman 0:38ceb79fef03 289 for( i = 0; i < MBEDTLS_CTR_DRBG_SEEDLEN; i++ )
kevman 0:38ceb79fef03 290 tmp[i] ^= data[i];
kevman 0:38ceb79fef03 291
kevman 0:38ceb79fef03 292 /*
kevman 0:38ceb79fef03 293 * Update key and counter
kevman 0:38ceb79fef03 294 */
kevman 0:38ceb79fef03 295 if( ( ret = mbedtls_aes_setkey_enc( &ctx->aes_ctx, tmp, MBEDTLS_CTR_DRBG_KEYBITS ) ) != 0 )
kevman 0:38ceb79fef03 296 {
kevman 0:38ceb79fef03 297 return( ret );
kevman 0:38ceb79fef03 298 }
kevman 0:38ceb79fef03 299 memcpy( ctx->counter, tmp + MBEDTLS_CTR_DRBG_KEYSIZE, MBEDTLS_CTR_DRBG_BLOCKSIZE );
kevman 0:38ceb79fef03 300
kevman 0:38ceb79fef03 301 return( 0 );
kevman 0:38ceb79fef03 302 }
kevman 0:38ceb79fef03 303
kevman 0:38ceb79fef03 304 void mbedtls_ctr_drbg_update( mbedtls_ctr_drbg_context *ctx,
kevman 0:38ceb79fef03 305 const unsigned char *additional, size_t add_len )
kevman 0:38ceb79fef03 306 {
kevman 0:38ceb79fef03 307 unsigned char add_input[MBEDTLS_CTR_DRBG_SEEDLEN];
kevman 0:38ceb79fef03 308
kevman 0:38ceb79fef03 309 if( add_len > 0 )
kevman 0:38ceb79fef03 310 {
kevman 0:38ceb79fef03 311 /* MAX_INPUT would be more logical here, but we have to match
kevman 0:38ceb79fef03 312 * block_cipher_df()'s limits since we can't propagate errors */
kevman 0:38ceb79fef03 313 if( add_len > MBEDTLS_CTR_DRBG_MAX_SEED_INPUT )
kevman 0:38ceb79fef03 314 add_len = MBEDTLS_CTR_DRBG_MAX_SEED_INPUT;
kevman 0:38ceb79fef03 315
kevman 0:38ceb79fef03 316 block_cipher_df( add_input, additional, add_len );
kevman 0:38ceb79fef03 317 ctr_drbg_update_internal( ctx, add_input );
kevman 0:38ceb79fef03 318 }
kevman 0:38ceb79fef03 319 }
kevman 0:38ceb79fef03 320
kevman 0:38ceb79fef03 321 int mbedtls_ctr_drbg_reseed( mbedtls_ctr_drbg_context *ctx,
kevman 0:38ceb79fef03 322 const unsigned char *additional, size_t len )
kevman 0:38ceb79fef03 323 {
kevman 0:38ceb79fef03 324 unsigned char seed[MBEDTLS_CTR_DRBG_MAX_SEED_INPUT];
kevman 0:38ceb79fef03 325 size_t seedlen = 0;
kevman 0:38ceb79fef03 326 int ret;
kevman 0:38ceb79fef03 327
kevman 0:38ceb79fef03 328 if( ctx->entropy_len > MBEDTLS_CTR_DRBG_MAX_SEED_INPUT ||
kevman 0:38ceb79fef03 329 len > MBEDTLS_CTR_DRBG_MAX_SEED_INPUT - ctx->entropy_len )
kevman 0:38ceb79fef03 330 return( MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG );
kevman 0:38ceb79fef03 331
kevman 0:38ceb79fef03 332 memset( seed, 0, MBEDTLS_CTR_DRBG_MAX_SEED_INPUT );
kevman 0:38ceb79fef03 333
kevman 0:38ceb79fef03 334 /*
kevman 0:38ceb79fef03 335 * Gather entropy_len bytes of entropy to seed state
kevman 0:38ceb79fef03 336 */
kevman 0:38ceb79fef03 337 if( 0 != ctx->f_entropy( ctx->p_entropy, seed,
kevman 0:38ceb79fef03 338 ctx->entropy_len ) )
kevman 0:38ceb79fef03 339 {
kevman 0:38ceb79fef03 340 return( MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED );
kevman 0:38ceb79fef03 341 }
kevman 0:38ceb79fef03 342
kevman 0:38ceb79fef03 343 seedlen += ctx->entropy_len;
kevman 0:38ceb79fef03 344
kevman 0:38ceb79fef03 345 /*
kevman 0:38ceb79fef03 346 * Add additional data
kevman 0:38ceb79fef03 347 */
kevman 0:38ceb79fef03 348 if( additional && len )
kevman 0:38ceb79fef03 349 {
kevman 0:38ceb79fef03 350 memcpy( seed + seedlen, additional, len );
kevman 0:38ceb79fef03 351 seedlen += len;
kevman 0:38ceb79fef03 352 }
kevman 0:38ceb79fef03 353
kevman 0:38ceb79fef03 354 /*
kevman 0:38ceb79fef03 355 * Reduce to 384 bits
kevman 0:38ceb79fef03 356 */
kevman 0:38ceb79fef03 357 if( ( ret = block_cipher_df( seed, seed, seedlen ) ) != 0 )
kevman 0:38ceb79fef03 358 {
kevman 0:38ceb79fef03 359 return( ret );
kevman 0:38ceb79fef03 360 }
kevman 0:38ceb79fef03 361
kevman 0:38ceb79fef03 362 /*
kevman 0:38ceb79fef03 363 * Update state
kevman 0:38ceb79fef03 364 */
kevman 0:38ceb79fef03 365 if( ( ret = ctr_drbg_update_internal( ctx, seed ) ) != 0 )
kevman 0:38ceb79fef03 366 {
kevman 0:38ceb79fef03 367 return( ret );
kevman 0:38ceb79fef03 368 }
kevman 0:38ceb79fef03 369 ctx->reseed_counter = 1;
kevman 0:38ceb79fef03 370
kevman 0:38ceb79fef03 371 return( 0 );
kevman 0:38ceb79fef03 372 }
kevman 0:38ceb79fef03 373
kevman 0:38ceb79fef03 374 int mbedtls_ctr_drbg_random_with_add( void *p_rng,
kevman 0:38ceb79fef03 375 unsigned char *output, size_t output_len,
kevman 0:38ceb79fef03 376 const unsigned char *additional, size_t add_len )
kevman 0:38ceb79fef03 377 {
kevman 0:38ceb79fef03 378 int ret = 0;
kevman 0:38ceb79fef03 379 mbedtls_ctr_drbg_context *ctx = (mbedtls_ctr_drbg_context *) p_rng;
kevman 0:38ceb79fef03 380 unsigned char add_input[MBEDTLS_CTR_DRBG_SEEDLEN];
kevman 0:38ceb79fef03 381 unsigned char *p = output;
kevman 0:38ceb79fef03 382 unsigned char tmp[MBEDTLS_CTR_DRBG_BLOCKSIZE];
kevman 0:38ceb79fef03 383 int i;
kevman 0:38ceb79fef03 384 size_t use_len;
kevman 0:38ceb79fef03 385
kevman 0:38ceb79fef03 386 if( output_len > MBEDTLS_CTR_DRBG_MAX_REQUEST )
kevman 0:38ceb79fef03 387 return( MBEDTLS_ERR_CTR_DRBG_REQUEST_TOO_BIG );
kevman 0:38ceb79fef03 388
kevman 0:38ceb79fef03 389 if( add_len > MBEDTLS_CTR_DRBG_MAX_INPUT )
kevman 0:38ceb79fef03 390 return( MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG );
kevman 0:38ceb79fef03 391
kevman 0:38ceb79fef03 392 memset( add_input, 0, MBEDTLS_CTR_DRBG_SEEDLEN );
kevman 0:38ceb79fef03 393
kevman 0:38ceb79fef03 394 if( ctx->reseed_counter > ctx->reseed_interval ||
kevman 0:38ceb79fef03 395 ctx->prediction_resistance )
kevman 0:38ceb79fef03 396 {
kevman 0:38ceb79fef03 397 if( ( ret = mbedtls_ctr_drbg_reseed( ctx, additional, add_len ) ) != 0 )
kevman 0:38ceb79fef03 398 {
kevman 0:38ceb79fef03 399 return( ret );
kevman 0:38ceb79fef03 400 }
kevman 0:38ceb79fef03 401 add_len = 0;
kevman 0:38ceb79fef03 402 }
kevman 0:38ceb79fef03 403
kevman 0:38ceb79fef03 404 if( add_len > 0 )
kevman 0:38ceb79fef03 405 {
kevman 0:38ceb79fef03 406 if( ( ret = block_cipher_df( add_input, additional, add_len ) ) != 0 )
kevman 0:38ceb79fef03 407 {
kevman 0:38ceb79fef03 408 return( ret );
kevman 0:38ceb79fef03 409 }
kevman 0:38ceb79fef03 410 if( ( ret = ctr_drbg_update_internal( ctx, add_input ) ) != 0 )
kevman 0:38ceb79fef03 411 {
kevman 0:38ceb79fef03 412 return( ret );
kevman 0:38ceb79fef03 413 }
kevman 0:38ceb79fef03 414 }
kevman 0:38ceb79fef03 415
kevman 0:38ceb79fef03 416 while( output_len > 0 )
kevman 0:38ceb79fef03 417 {
kevman 0:38ceb79fef03 418 /*
kevman 0:38ceb79fef03 419 * Increase counter
kevman 0:38ceb79fef03 420 */
kevman 0:38ceb79fef03 421 for( i = MBEDTLS_CTR_DRBG_BLOCKSIZE; i > 0; i-- )
kevman 0:38ceb79fef03 422 if( ++ctx->counter[i - 1] != 0 )
kevman 0:38ceb79fef03 423 break;
kevman 0:38ceb79fef03 424
kevman 0:38ceb79fef03 425 /*
kevman 0:38ceb79fef03 426 * Crypt counter block
kevman 0:38ceb79fef03 427 */
kevman 0:38ceb79fef03 428 if( ( ret = mbedtls_aes_crypt_ecb( &ctx->aes_ctx, MBEDTLS_AES_ENCRYPT, ctx->counter, tmp ) ) != 0 )
kevman 0:38ceb79fef03 429 {
kevman 0:38ceb79fef03 430 return( ret );
kevman 0:38ceb79fef03 431 }
kevman 0:38ceb79fef03 432
kevman 0:38ceb79fef03 433 use_len = ( output_len > MBEDTLS_CTR_DRBG_BLOCKSIZE ) ? MBEDTLS_CTR_DRBG_BLOCKSIZE :
kevman 0:38ceb79fef03 434 output_len;
kevman 0:38ceb79fef03 435 /*
kevman 0:38ceb79fef03 436 * Copy random block to destination
kevman 0:38ceb79fef03 437 */
kevman 0:38ceb79fef03 438 memcpy( p, tmp, use_len );
kevman 0:38ceb79fef03 439 p += use_len;
kevman 0:38ceb79fef03 440 output_len -= use_len;
kevman 0:38ceb79fef03 441 }
kevman 0:38ceb79fef03 442
kevman 0:38ceb79fef03 443 if( ( ret = ctr_drbg_update_internal( ctx, add_input ) ) != 0 )
kevman 0:38ceb79fef03 444 {
kevman 0:38ceb79fef03 445 return( ret );
kevman 0:38ceb79fef03 446 }
kevman 0:38ceb79fef03 447
kevman 0:38ceb79fef03 448 ctx->reseed_counter++;
kevman 0:38ceb79fef03 449
kevman 0:38ceb79fef03 450 return( 0 );
kevman 0:38ceb79fef03 451 }
kevman 0:38ceb79fef03 452
kevman 0:38ceb79fef03 453 int mbedtls_ctr_drbg_random( void *p_rng, unsigned char *output, size_t output_len )
kevman 0:38ceb79fef03 454 {
kevman 0:38ceb79fef03 455 int ret;
kevman 0:38ceb79fef03 456 mbedtls_ctr_drbg_context *ctx = (mbedtls_ctr_drbg_context *) p_rng;
kevman 0:38ceb79fef03 457
kevman 0:38ceb79fef03 458 #if defined(MBEDTLS_THREADING_C)
kevman 0:38ceb79fef03 459 if( ( ret = mbedtls_mutex_lock( &ctx->mutex ) ) != 0 )
kevman 0:38ceb79fef03 460 return( ret );
kevman 0:38ceb79fef03 461 #endif
kevman 0:38ceb79fef03 462
kevman 0:38ceb79fef03 463 ret = mbedtls_ctr_drbg_random_with_add( ctx, output, output_len, NULL, 0 );
kevman 0:38ceb79fef03 464
kevman 0:38ceb79fef03 465 #if defined(MBEDTLS_THREADING_C)
kevman 0:38ceb79fef03 466 if( mbedtls_mutex_unlock( &ctx->mutex ) != 0 )
kevman 0:38ceb79fef03 467 return( MBEDTLS_ERR_THREADING_MUTEX_ERROR );
kevman 0:38ceb79fef03 468 #endif
kevman 0:38ceb79fef03 469
kevman 0:38ceb79fef03 470 return( ret );
kevman 0:38ceb79fef03 471 }
kevman 0:38ceb79fef03 472
kevman 0:38ceb79fef03 473 #if defined(MBEDTLS_FS_IO)
kevman 0:38ceb79fef03 474 int mbedtls_ctr_drbg_write_seed_file( mbedtls_ctr_drbg_context *ctx, const char *path )
kevman 0:38ceb79fef03 475 {
kevman 0:38ceb79fef03 476 int ret = MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR;
kevman 0:38ceb79fef03 477 FILE *f;
kevman 0:38ceb79fef03 478 unsigned char buf[ MBEDTLS_CTR_DRBG_MAX_INPUT ];
kevman 0:38ceb79fef03 479
kevman 0:38ceb79fef03 480 if( ( f = fopen( path, "wb" ) ) == NULL )
kevman 0:38ceb79fef03 481 return( MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR );
kevman 0:38ceb79fef03 482
kevman 0:38ceb79fef03 483 if( ( ret = mbedtls_ctr_drbg_random( ctx, buf, MBEDTLS_CTR_DRBG_MAX_INPUT ) ) != 0 )
kevman 0:38ceb79fef03 484 goto exit;
kevman 0:38ceb79fef03 485
kevman 0:38ceb79fef03 486 if( fwrite( buf, 1, MBEDTLS_CTR_DRBG_MAX_INPUT, f ) != MBEDTLS_CTR_DRBG_MAX_INPUT )
kevman 0:38ceb79fef03 487 ret = MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR;
kevman 0:38ceb79fef03 488 else
kevman 0:38ceb79fef03 489 ret = 0;
kevman 0:38ceb79fef03 490
kevman 0:38ceb79fef03 491 exit:
kevman 0:38ceb79fef03 492 mbedtls_platform_zeroize( buf, sizeof( buf ) );
kevman 0:38ceb79fef03 493
kevman 0:38ceb79fef03 494 fclose( f );
kevman 0:38ceb79fef03 495 return( ret );
kevman 0:38ceb79fef03 496 }
kevman 0:38ceb79fef03 497
kevman 0:38ceb79fef03 498 int mbedtls_ctr_drbg_update_seed_file( mbedtls_ctr_drbg_context *ctx, const char *path )
kevman 0:38ceb79fef03 499 {
kevman 0:38ceb79fef03 500 int ret = 0;
kevman 0:38ceb79fef03 501 FILE *f;
kevman 0:38ceb79fef03 502 size_t n;
kevman 0:38ceb79fef03 503 unsigned char buf[ MBEDTLS_CTR_DRBG_MAX_INPUT ];
kevman 0:38ceb79fef03 504
kevman 0:38ceb79fef03 505 if( ( f = fopen( path, "rb" ) ) == NULL )
kevman 0:38ceb79fef03 506 return( MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR );
kevman 0:38ceb79fef03 507
kevman 0:38ceb79fef03 508 fseek( f, 0, SEEK_END );
kevman 0:38ceb79fef03 509 n = (size_t) ftell( f );
kevman 0:38ceb79fef03 510 fseek( f, 0, SEEK_SET );
kevman 0:38ceb79fef03 511
kevman 0:38ceb79fef03 512 if( n > MBEDTLS_CTR_DRBG_MAX_INPUT )
kevman 0:38ceb79fef03 513 {
kevman 0:38ceb79fef03 514 fclose( f );
kevman 0:38ceb79fef03 515 return( MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG );
kevman 0:38ceb79fef03 516 }
kevman 0:38ceb79fef03 517
kevman 0:38ceb79fef03 518 if( fread( buf, 1, n, f ) != n )
kevman 0:38ceb79fef03 519 ret = MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR;
kevman 0:38ceb79fef03 520 else
kevman 0:38ceb79fef03 521 mbedtls_ctr_drbg_update( ctx, buf, n );
kevman 0:38ceb79fef03 522
kevman 0:38ceb79fef03 523 fclose( f );
kevman 0:38ceb79fef03 524
kevman 0:38ceb79fef03 525 mbedtls_platform_zeroize( buf, sizeof( buf ) );
kevman 0:38ceb79fef03 526
kevman 0:38ceb79fef03 527 if( ret != 0 )
kevman 0:38ceb79fef03 528 return( ret );
kevman 0:38ceb79fef03 529
kevman 0:38ceb79fef03 530 return( mbedtls_ctr_drbg_write_seed_file( ctx, path ) );
kevman 0:38ceb79fef03 531 }
kevman 0:38ceb79fef03 532 #endif /* MBEDTLS_FS_IO */
kevman 0:38ceb79fef03 533
kevman 0:38ceb79fef03 534 #if defined(MBEDTLS_SELF_TEST)
kevman 0:38ceb79fef03 535
kevman 0:38ceb79fef03 536 static const unsigned char entropy_source_pr[96] =
kevman 0:38ceb79fef03 537 { 0xc1, 0x80, 0x81, 0xa6, 0x5d, 0x44, 0x02, 0x16,
kevman 0:38ceb79fef03 538 0x19, 0xb3, 0xf1, 0x80, 0xb1, 0xc9, 0x20, 0x02,
kevman 0:38ceb79fef03 539 0x6a, 0x54, 0x6f, 0x0c, 0x70, 0x81, 0x49, 0x8b,
kevman 0:38ceb79fef03 540 0x6e, 0xa6, 0x62, 0x52, 0x6d, 0x51, 0xb1, 0xcb,
kevman 0:38ceb79fef03 541 0x58, 0x3b, 0xfa, 0xd5, 0x37, 0x5f, 0xfb, 0xc9,
kevman 0:38ceb79fef03 542 0xff, 0x46, 0xd2, 0x19, 0xc7, 0x22, 0x3e, 0x95,
kevman 0:38ceb79fef03 543 0x45, 0x9d, 0x82, 0xe1, 0xe7, 0x22, 0x9f, 0x63,
kevman 0:38ceb79fef03 544 0x31, 0x69, 0xd2, 0x6b, 0x57, 0x47, 0x4f, 0xa3,
kevman 0:38ceb79fef03 545 0x37, 0xc9, 0x98, 0x1c, 0x0b, 0xfb, 0x91, 0x31,
kevman 0:38ceb79fef03 546 0x4d, 0x55, 0xb9, 0xe9, 0x1c, 0x5a, 0x5e, 0xe4,
kevman 0:38ceb79fef03 547 0x93, 0x92, 0xcf, 0xc5, 0x23, 0x12, 0xd5, 0x56,
kevman 0:38ceb79fef03 548 0x2c, 0x4a, 0x6e, 0xff, 0xdc, 0x10, 0xd0, 0x68 };
kevman 0:38ceb79fef03 549
kevman 0:38ceb79fef03 550 static const unsigned char entropy_source_nopr[64] =
kevman 0:38ceb79fef03 551 { 0x5a, 0x19, 0x4d, 0x5e, 0x2b, 0x31, 0x58, 0x14,
kevman 0:38ceb79fef03 552 0x54, 0xde, 0xf6, 0x75, 0xfb, 0x79, 0x58, 0xfe,
kevman 0:38ceb79fef03 553 0xc7, 0xdb, 0x87, 0x3e, 0x56, 0x89, 0xfc, 0x9d,
kevman 0:38ceb79fef03 554 0x03, 0x21, 0x7c, 0x68, 0xd8, 0x03, 0x38, 0x20,
kevman 0:38ceb79fef03 555 0xf9, 0xe6, 0x5e, 0x04, 0xd8, 0x56, 0xf3, 0xa9,
kevman 0:38ceb79fef03 556 0xc4, 0x4a, 0x4c, 0xbd, 0xc1, 0xd0, 0x08, 0x46,
kevman 0:38ceb79fef03 557 0xf5, 0x98, 0x3d, 0x77, 0x1c, 0x1b, 0x13, 0x7e,
kevman 0:38ceb79fef03 558 0x4e, 0x0f, 0x9d, 0x8e, 0xf4, 0x09, 0xf9, 0x2e };
kevman 0:38ceb79fef03 559
kevman 0:38ceb79fef03 560 static const unsigned char nonce_pers_pr[16] =
kevman 0:38ceb79fef03 561 { 0xd2, 0x54, 0xfc, 0xff, 0x02, 0x1e, 0x69, 0xd2,
kevman 0:38ceb79fef03 562 0x29, 0xc9, 0xcf, 0xad, 0x85, 0xfa, 0x48, 0x6c };
kevman 0:38ceb79fef03 563
kevman 0:38ceb79fef03 564 static const unsigned char nonce_pers_nopr[16] =
kevman 0:38ceb79fef03 565 { 0x1b, 0x54, 0xb8, 0xff, 0x06, 0x42, 0xbf, 0xf5,
kevman 0:38ceb79fef03 566 0x21, 0xf1, 0x5c, 0x1c, 0x0b, 0x66, 0x5f, 0x3f };
kevman 0:38ceb79fef03 567
kevman 0:38ceb79fef03 568 static const unsigned char result_pr[16] =
kevman 0:38ceb79fef03 569 { 0x34, 0x01, 0x16, 0x56, 0xb4, 0x29, 0x00, 0x8f,
kevman 0:38ceb79fef03 570 0x35, 0x63, 0xec, 0xb5, 0xf2, 0x59, 0x07, 0x23 };
kevman 0:38ceb79fef03 571
kevman 0:38ceb79fef03 572 static const unsigned char result_nopr[16] =
kevman 0:38ceb79fef03 573 { 0xa0, 0x54, 0x30, 0x3d, 0x8a, 0x7e, 0xa9, 0x88,
kevman 0:38ceb79fef03 574 0x9d, 0x90, 0x3e, 0x07, 0x7c, 0x6f, 0x21, 0x8f };
kevman 0:38ceb79fef03 575
kevman 0:38ceb79fef03 576 static size_t test_offset;
kevman 0:38ceb79fef03 577 static int ctr_drbg_self_test_entropy( void *data, unsigned char *buf,
kevman 0:38ceb79fef03 578 size_t len )
kevman 0:38ceb79fef03 579 {
kevman 0:38ceb79fef03 580 const unsigned char *p = data;
kevman 0:38ceb79fef03 581 memcpy( buf, p + test_offset, len );
kevman 0:38ceb79fef03 582 test_offset += len;
kevman 0:38ceb79fef03 583 return( 0 );
kevman 0:38ceb79fef03 584 }
kevman 0:38ceb79fef03 585
kevman 0:38ceb79fef03 586 #define CHK( c ) if( (c) != 0 ) \
kevman 0:38ceb79fef03 587 { \
kevman 0:38ceb79fef03 588 if( verbose != 0 ) \
kevman 0:38ceb79fef03 589 mbedtls_printf( "failed\n" ); \
kevman 0:38ceb79fef03 590 return( 1 ); \
kevman 0:38ceb79fef03 591 }
kevman 0:38ceb79fef03 592
kevman 0:38ceb79fef03 593 /*
kevman 0:38ceb79fef03 594 * Checkup routine
kevman 0:38ceb79fef03 595 */
kevman 0:38ceb79fef03 596 int mbedtls_ctr_drbg_self_test( int verbose )
kevman 0:38ceb79fef03 597 {
kevman 0:38ceb79fef03 598 mbedtls_ctr_drbg_context ctx;
kevman 0:38ceb79fef03 599 unsigned char buf[16];
kevman 0:38ceb79fef03 600
kevman 0:38ceb79fef03 601 mbedtls_ctr_drbg_init( &ctx );
kevman 0:38ceb79fef03 602
kevman 0:38ceb79fef03 603 /*
kevman 0:38ceb79fef03 604 * Based on a NIST CTR_DRBG test vector (PR = True)
kevman 0:38ceb79fef03 605 */
kevman 0:38ceb79fef03 606 if( verbose != 0 )
kevman 0:38ceb79fef03 607 mbedtls_printf( " CTR_DRBG (PR = TRUE) : " );
kevman 0:38ceb79fef03 608
kevman 0:38ceb79fef03 609 test_offset = 0;
kevman 0:38ceb79fef03 610 CHK( mbedtls_ctr_drbg_seed_entropy_len( &ctx, ctr_drbg_self_test_entropy,
kevman 0:38ceb79fef03 611 (void *) entropy_source_pr, nonce_pers_pr, 16, 32 ) );
kevman 0:38ceb79fef03 612 mbedtls_ctr_drbg_set_prediction_resistance( &ctx, MBEDTLS_CTR_DRBG_PR_ON );
kevman 0:38ceb79fef03 613 CHK( mbedtls_ctr_drbg_random( &ctx, buf, MBEDTLS_CTR_DRBG_BLOCKSIZE ) );
kevman 0:38ceb79fef03 614 CHK( mbedtls_ctr_drbg_random( &ctx, buf, MBEDTLS_CTR_DRBG_BLOCKSIZE ) );
kevman 0:38ceb79fef03 615 CHK( memcmp( buf, result_pr, MBEDTLS_CTR_DRBG_BLOCKSIZE ) );
kevman 0:38ceb79fef03 616
kevman 0:38ceb79fef03 617 mbedtls_ctr_drbg_free( &ctx );
kevman 0:38ceb79fef03 618
kevman 0:38ceb79fef03 619 if( verbose != 0 )
kevman 0:38ceb79fef03 620 mbedtls_printf( "passed\n" );
kevman 0:38ceb79fef03 621
kevman 0:38ceb79fef03 622 /*
kevman 0:38ceb79fef03 623 * Based on a NIST CTR_DRBG test vector (PR = FALSE)
kevman 0:38ceb79fef03 624 */
kevman 0:38ceb79fef03 625 if( verbose != 0 )
kevman 0:38ceb79fef03 626 mbedtls_printf( " CTR_DRBG (PR = FALSE): " );
kevman 0:38ceb79fef03 627
kevman 0:38ceb79fef03 628 mbedtls_ctr_drbg_init( &ctx );
kevman 0:38ceb79fef03 629
kevman 0:38ceb79fef03 630 test_offset = 0;
kevman 0:38ceb79fef03 631 CHK( mbedtls_ctr_drbg_seed_entropy_len( &ctx, ctr_drbg_self_test_entropy,
kevman 0:38ceb79fef03 632 (void *) entropy_source_nopr, nonce_pers_nopr, 16, 32 ) );
kevman 0:38ceb79fef03 633 CHK( mbedtls_ctr_drbg_random( &ctx, buf, 16 ) );
kevman 0:38ceb79fef03 634 CHK( mbedtls_ctr_drbg_reseed( &ctx, NULL, 0 ) );
kevman 0:38ceb79fef03 635 CHK( mbedtls_ctr_drbg_random( &ctx, buf, 16 ) );
kevman 0:38ceb79fef03 636 CHK( memcmp( buf, result_nopr, 16 ) );
kevman 0:38ceb79fef03 637
kevman 0:38ceb79fef03 638 mbedtls_ctr_drbg_free( &ctx );
kevman 0:38ceb79fef03 639
kevman 0:38ceb79fef03 640 if( verbose != 0 )
kevman 0:38ceb79fef03 641 mbedtls_printf( "passed\n" );
kevman 0:38ceb79fef03 642
kevman 0:38ceb79fef03 643 if( verbose != 0 )
kevman 0:38ceb79fef03 644 mbedtls_printf( "\n" );
kevman 0:38ceb79fef03 645
kevman 0:38ceb79fef03 646 return( 0 );
kevman 0:38ceb79fef03 647 }
kevman 0:38ceb79fef03 648 #endif /* MBEDTLS_SELF_TEST */
kevman 0:38ceb79fef03 649
kevman 0:38ceb79fef03 650 #endif /* MBEDTLS_CTR_DRBG_C */