mbed-os

Dependents:   cobaLCDJoyMotor_Thread odometry_omni_3roda_v3 odometry_omni_3roda_v1 odometry_omni_3roda_v2 ... more

Committer:
be_bryan
Date:
Mon Dec 11 17:54:04 2017 +0000
Revision:
0:b74591d5ab33
motor ++

Who changed what in which revision?

UserRevisionLine numberNew contents of line
be_bryan 0:b74591d5ab33 1 /*
be_bryan 0:b74591d5ab33 2 * Entropy accumulator implementation
be_bryan 0:b74591d5ab33 3 *
be_bryan 0:b74591d5ab33 4 * Copyright (C) 2006-2016, ARM Limited, All Rights Reserved
be_bryan 0:b74591d5ab33 5 * SPDX-License-Identifier: Apache-2.0
be_bryan 0:b74591d5ab33 6 *
be_bryan 0:b74591d5ab33 7 * Licensed under the Apache License, Version 2.0 (the "License"); you may
be_bryan 0:b74591d5ab33 8 * not use this file except in compliance with the License.
be_bryan 0:b74591d5ab33 9 * You may obtain a copy of the License at
be_bryan 0:b74591d5ab33 10 *
be_bryan 0:b74591d5ab33 11 * http://www.apache.org/licenses/LICENSE-2.0
be_bryan 0:b74591d5ab33 12 *
be_bryan 0:b74591d5ab33 13 * Unless required by applicable law or agreed to in writing, software
be_bryan 0:b74591d5ab33 14 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
be_bryan 0:b74591d5ab33 15 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
be_bryan 0:b74591d5ab33 16 * See the License for the specific language governing permissions and
be_bryan 0:b74591d5ab33 17 * limitations under the License.
be_bryan 0:b74591d5ab33 18 *
be_bryan 0:b74591d5ab33 19 * This file is part of mbed TLS (https://tls.mbed.org)
be_bryan 0:b74591d5ab33 20 */
be_bryan 0:b74591d5ab33 21
be_bryan 0:b74591d5ab33 22 #if !defined(MBEDTLS_CONFIG_FILE)
be_bryan 0:b74591d5ab33 23 #include "mbedtls/config.h"
be_bryan 0:b74591d5ab33 24 #else
be_bryan 0:b74591d5ab33 25 #include MBEDTLS_CONFIG_FILE
be_bryan 0:b74591d5ab33 26 #endif
be_bryan 0:b74591d5ab33 27
be_bryan 0:b74591d5ab33 28 #if defined(MBEDTLS_ENTROPY_C)
be_bryan 0:b74591d5ab33 29
be_bryan 0:b74591d5ab33 30 #if defined(MBEDTLS_TEST_NULL_ENTROPY)
be_bryan 0:b74591d5ab33 31 #warning "**** WARNING! MBEDTLS_TEST_NULL_ENTROPY defined! "
be_bryan 0:b74591d5ab33 32 #warning "**** THIS BUILD HAS NO DEFINED ENTROPY SOURCES "
be_bryan 0:b74591d5ab33 33 #warning "**** THIS BUILD IS *NOT* SUITABLE FOR PRODUCTION USE "
be_bryan 0:b74591d5ab33 34 #endif
be_bryan 0:b74591d5ab33 35
be_bryan 0:b74591d5ab33 36 #include "mbedtls/entropy.h"
be_bryan 0:b74591d5ab33 37 #include "mbedtls/entropy_poll.h"
be_bryan 0:b74591d5ab33 38
be_bryan 0:b74591d5ab33 39 #include <string.h>
be_bryan 0:b74591d5ab33 40
be_bryan 0:b74591d5ab33 41 #if defined(MBEDTLS_FS_IO)
be_bryan 0:b74591d5ab33 42 #include <stdio.h>
be_bryan 0:b74591d5ab33 43 #endif
be_bryan 0:b74591d5ab33 44
be_bryan 0:b74591d5ab33 45 #if defined(MBEDTLS_ENTROPY_NV_SEED)
be_bryan 0:b74591d5ab33 46 #include "mbedtls/platform.h"
be_bryan 0:b74591d5ab33 47 #endif
be_bryan 0:b74591d5ab33 48
be_bryan 0:b74591d5ab33 49 #if defined(MBEDTLS_SELF_TEST)
be_bryan 0:b74591d5ab33 50 #if defined(MBEDTLS_PLATFORM_C)
be_bryan 0:b74591d5ab33 51 #include "mbedtls/platform.h"
be_bryan 0:b74591d5ab33 52 #else
be_bryan 0:b74591d5ab33 53 #include <stdio.h>
be_bryan 0:b74591d5ab33 54 #define mbedtls_printf printf
be_bryan 0:b74591d5ab33 55 #endif /* MBEDTLS_PLATFORM_C */
be_bryan 0:b74591d5ab33 56 #endif /* MBEDTLS_SELF_TEST */
be_bryan 0:b74591d5ab33 57
be_bryan 0:b74591d5ab33 58 #if defined(MBEDTLS_HAVEGE_C)
be_bryan 0:b74591d5ab33 59 #include "mbedtls/havege.h"
be_bryan 0:b74591d5ab33 60 #endif
be_bryan 0:b74591d5ab33 61
be_bryan 0:b74591d5ab33 62 /* Implementation that should never be optimized out by the compiler */
be_bryan 0:b74591d5ab33 63 static void mbedtls_zeroize( void *v, size_t n ) {
be_bryan 0:b74591d5ab33 64 volatile unsigned char *p = v; while( n-- ) *p++ = 0;
be_bryan 0:b74591d5ab33 65 }
be_bryan 0:b74591d5ab33 66
be_bryan 0:b74591d5ab33 67 #define ENTROPY_MAX_LOOP 256 /**< Maximum amount to loop before error */
be_bryan 0:b74591d5ab33 68
be_bryan 0:b74591d5ab33 69 void mbedtls_entropy_init( mbedtls_entropy_context *ctx )
be_bryan 0:b74591d5ab33 70 {
be_bryan 0:b74591d5ab33 71 memset( ctx, 0, sizeof(mbedtls_entropy_context) );
be_bryan 0:b74591d5ab33 72
be_bryan 0:b74591d5ab33 73 #if defined(MBEDTLS_THREADING_C)
be_bryan 0:b74591d5ab33 74 mbedtls_mutex_init( &ctx->mutex );
be_bryan 0:b74591d5ab33 75 #endif
be_bryan 0:b74591d5ab33 76
be_bryan 0:b74591d5ab33 77 #if defined(MBEDTLS_ENTROPY_SHA512_ACCUMULATOR)
be_bryan 0:b74591d5ab33 78 mbedtls_sha512_starts( &ctx->accumulator, 0 );
be_bryan 0:b74591d5ab33 79 #else
be_bryan 0:b74591d5ab33 80 mbedtls_sha256_starts( &ctx->accumulator, 0 );
be_bryan 0:b74591d5ab33 81 #endif
be_bryan 0:b74591d5ab33 82 #if defined(MBEDTLS_HAVEGE_C)
be_bryan 0:b74591d5ab33 83 mbedtls_havege_init( &ctx->havege_data );
be_bryan 0:b74591d5ab33 84 #endif
be_bryan 0:b74591d5ab33 85
be_bryan 0:b74591d5ab33 86 #if defined(MBEDTLS_TEST_NULL_ENTROPY)
be_bryan 0:b74591d5ab33 87 mbedtls_entropy_add_source( ctx, mbedtls_null_entropy_poll, NULL,
be_bryan 0:b74591d5ab33 88 1, MBEDTLS_ENTROPY_SOURCE_STRONG );
be_bryan 0:b74591d5ab33 89 #endif
be_bryan 0:b74591d5ab33 90
be_bryan 0:b74591d5ab33 91 #if !defined(MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES)
be_bryan 0:b74591d5ab33 92 #if !defined(MBEDTLS_NO_PLATFORM_ENTROPY)
be_bryan 0:b74591d5ab33 93 mbedtls_entropy_add_source( ctx, mbedtls_platform_entropy_poll, NULL,
be_bryan 0:b74591d5ab33 94 MBEDTLS_ENTROPY_MIN_PLATFORM,
be_bryan 0:b74591d5ab33 95 MBEDTLS_ENTROPY_SOURCE_STRONG );
be_bryan 0:b74591d5ab33 96 #endif
be_bryan 0:b74591d5ab33 97 #if defined(MBEDTLS_TIMING_C)
be_bryan 0:b74591d5ab33 98 mbedtls_entropy_add_source( ctx, mbedtls_hardclock_poll, NULL,
be_bryan 0:b74591d5ab33 99 MBEDTLS_ENTROPY_MIN_HARDCLOCK,
be_bryan 0:b74591d5ab33 100 MBEDTLS_ENTROPY_SOURCE_WEAK );
be_bryan 0:b74591d5ab33 101 #endif
be_bryan 0:b74591d5ab33 102 #if defined(MBEDTLS_HAVEGE_C)
be_bryan 0:b74591d5ab33 103 mbedtls_entropy_add_source( ctx, mbedtls_havege_poll, &ctx->havege_data,
be_bryan 0:b74591d5ab33 104 MBEDTLS_ENTROPY_MIN_HAVEGE,
be_bryan 0:b74591d5ab33 105 MBEDTLS_ENTROPY_SOURCE_STRONG );
be_bryan 0:b74591d5ab33 106 #endif
be_bryan 0:b74591d5ab33 107 #if defined(MBEDTLS_ENTROPY_HARDWARE_ALT)
be_bryan 0:b74591d5ab33 108 mbedtls_entropy_add_source( ctx, mbedtls_hardware_poll, NULL,
be_bryan 0:b74591d5ab33 109 MBEDTLS_ENTROPY_MIN_HARDWARE,
be_bryan 0:b74591d5ab33 110 MBEDTLS_ENTROPY_SOURCE_STRONG );
be_bryan 0:b74591d5ab33 111 #endif
be_bryan 0:b74591d5ab33 112 #if defined(MBEDTLS_ENTROPY_NV_SEED)
be_bryan 0:b74591d5ab33 113 mbedtls_entropy_add_source( ctx, mbedtls_nv_seed_poll, NULL,
be_bryan 0:b74591d5ab33 114 MBEDTLS_ENTROPY_BLOCK_SIZE,
be_bryan 0:b74591d5ab33 115 MBEDTLS_ENTROPY_SOURCE_STRONG );
be_bryan 0:b74591d5ab33 116 #endif
be_bryan 0:b74591d5ab33 117 #endif /* MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES */
be_bryan 0:b74591d5ab33 118 }
be_bryan 0:b74591d5ab33 119
be_bryan 0:b74591d5ab33 120 void mbedtls_entropy_free( mbedtls_entropy_context *ctx )
be_bryan 0:b74591d5ab33 121 {
be_bryan 0:b74591d5ab33 122 #if defined(MBEDTLS_HAVEGE_C)
be_bryan 0:b74591d5ab33 123 mbedtls_havege_free( &ctx->havege_data );
be_bryan 0:b74591d5ab33 124 #endif
be_bryan 0:b74591d5ab33 125 #if defined(MBEDTLS_THREADING_C)
be_bryan 0:b74591d5ab33 126 mbedtls_mutex_free( &ctx->mutex );
be_bryan 0:b74591d5ab33 127 #endif
be_bryan 0:b74591d5ab33 128 mbedtls_zeroize( ctx, sizeof( mbedtls_entropy_context ) );
be_bryan 0:b74591d5ab33 129 }
be_bryan 0:b74591d5ab33 130
be_bryan 0:b74591d5ab33 131 int mbedtls_entropy_add_source( mbedtls_entropy_context *ctx,
be_bryan 0:b74591d5ab33 132 mbedtls_entropy_f_source_ptr f_source, void *p_source,
be_bryan 0:b74591d5ab33 133 size_t threshold, int strong )
be_bryan 0:b74591d5ab33 134 {
be_bryan 0:b74591d5ab33 135 int idx, ret = 0;
be_bryan 0:b74591d5ab33 136
be_bryan 0:b74591d5ab33 137 #if defined(MBEDTLS_THREADING_C)
be_bryan 0:b74591d5ab33 138 if( ( ret = mbedtls_mutex_lock( &ctx->mutex ) ) != 0 )
be_bryan 0:b74591d5ab33 139 return( ret );
be_bryan 0:b74591d5ab33 140 #endif
be_bryan 0:b74591d5ab33 141
be_bryan 0:b74591d5ab33 142 idx = ctx->source_count;
be_bryan 0:b74591d5ab33 143 if( idx >= MBEDTLS_ENTROPY_MAX_SOURCES )
be_bryan 0:b74591d5ab33 144 {
be_bryan 0:b74591d5ab33 145 ret = MBEDTLS_ERR_ENTROPY_MAX_SOURCES;
be_bryan 0:b74591d5ab33 146 goto exit;
be_bryan 0:b74591d5ab33 147 }
be_bryan 0:b74591d5ab33 148
be_bryan 0:b74591d5ab33 149 ctx->source[idx].f_source = f_source;
be_bryan 0:b74591d5ab33 150 ctx->source[idx].p_source = p_source;
be_bryan 0:b74591d5ab33 151 ctx->source[idx].threshold = threshold;
be_bryan 0:b74591d5ab33 152 ctx->source[idx].strong = strong;
be_bryan 0:b74591d5ab33 153
be_bryan 0:b74591d5ab33 154 ctx->source_count++;
be_bryan 0:b74591d5ab33 155
be_bryan 0:b74591d5ab33 156 exit:
be_bryan 0:b74591d5ab33 157 #if defined(MBEDTLS_THREADING_C)
be_bryan 0:b74591d5ab33 158 if( mbedtls_mutex_unlock( &ctx->mutex ) != 0 )
be_bryan 0:b74591d5ab33 159 return( MBEDTLS_ERR_THREADING_MUTEX_ERROR );
be_bryan 0:b74591d5ab33 160 #endif
be_bryan 0:b74591d5ab33 161
be_bryan 0:b74591d5ab33 162 return( ret );
be_bryan 0:b74591d5ab33 163 }
be_bryan 0:b74591d5ab33 164
be_bryan 0:b74591d5ab33 165 /*
be_bryan 0:b74591d5ab33 166 * Entropy accumulator update
be_bryan 0:b74591d5ab33 167 */
be_bryan 0:b74591d5ab33 168 static int entropy_update( mbedtls_entropy_context *ctx, unsigned char source_id,
be_bryan 0:b74591d5ab33 169 const unsigned char *data, size_t len )
be_bryan 0:b74591d5ab33 170 {
be_bryan 0:b74591d5ab33 171 unsigned char header[2];
be_bryan 0:b74591d5ab33 172 unsigned char tmp[MBEDTLS_ENTROPY_BLOCK_SIZE];
be_bryan 0:b74591d5ab33 173 size_t use_len = len;
be_bryan 0:b74591d5ab33 174 const unsigned char *p = data;
be_bryan 0:b74591d5ab33 175
be_bryan 0:b74591d5ab33 176 if( use_len > MBEDTLS_ENTROPY_BLOCK_SIZE )
be_bryan 0:b74591d5ab33 177 {
be_bryan 0:b74591d5ab33 178 #if defined(MBEDTLS_ENTROPY_SHA512_ACCUMULATOR)
be_bryan 0:b74591d5ab33 179 mbedtls_sha512( data, len, tmp, 0 );
be_bryan 0:b74591d5ab33 180 #else
be_bryan 0:b74591d5ab33 181 mbedtls_sha256( data, len, tmp, 0 );
be_bryan 0:b74591d5ab33 182 #endif
be_bryan 0:b74591d5ab33 183 p = tmp;
be_bryan 0:b74591d5ab33 184 use_len = MBEDTLS_ENTROPY_BLOCK_SIZE;
be_bryan 0:b74591d5ab33 185 }
be_bryan 0:b74591d5ab33 186
be_bryan 0:b74591d5ab33 187 header[0] = source_id;
be_bryan 0:b74591d5ab33 188 header[1] = use_len & 0xFF;
be_bryan 0:b74591d5ab33 189
be_bryan 0:b74591d5ab33 190 #if defined(MBEDTLS_ENTROPY_SHA512_ACCUMULATOR)
be_bryan 0:b74591d5ab33 191 mbedtls_sha512_update( &ctx->accumulator, header, 2 );
be_bryan 0:b74591d5ab33 192 mbedtls_sha512_update( &ctx->accumulator, p, use_len );
be_bryan 0:b74591d5ab33 193 #else
be_bryan 0:b74591d5ab33 194 mbedtls_sha256_update( &ctx->accumulator, header, 2 );
be_bryan 0:b74591d5ab33 195 mbedtls_sha256_update( &ctx->accumulator, p, use_len );
be_bryan 0:b74591d5ab33 196 #endif
be_bryan 0:b74591d5ab33 197
be_bryan 0:b74591d5ab33 198 return( 0 );
be_bryan 0:b74591d5ab33 199 }
be_bryan 0:b74591d5ab33 200
be_bryan 0:b74591d5ab33 201 int mbedtls_entropy_update_manual( mbedtls_entropy_context *ctx,
be_bryan 0:b74591d5ab33 202 const unsigned char *data, size_t len )
be_bryan 0:b74591d5ab33 203 {
be_bryan 0:b74591d5ab33 204 int ret;
be_bryan 0:b74591d5ab33 205
be_bryan 0:b74591d5ab33 206 #if defined(MBEDTLS_THREADING_C)
be_bryan 0:b74591d5ab33 207 if( ( ret = mbedtls_mutex_lock( &ctx->mutex ) ) != 0 )
be_bryan 0:b74591d5ab33 208 return( ret );
be_bryan 0:b74591d5ab33 209 #endif
be_bryan 0:b74591d5ab33 210
be_bryan 0:b74591d5ab33 211 ret = entropy_update( ctx, MBEDTLS_ENTROPY_SOURCE_MANUAL, data, len );
be_bryan 0:b74591d5ab33 212
be_bryan 0:b74591d5ab33 213 #if defined(MBEDTLS_THREADING_C)
be_bryan 0:b74591d5ab33 214 if( mbedtls_mutex_unlock( &ctx->mutex ) != 0 )
be_bryan 0:b74591d5ab33 215 return( MBEDTLS_ERR_THREADING_MUTEX_ERROR );
be_bryan 0:b74591d5ab33 216 #endif
be_bryan 0:b74591d5ab33 217
be_bryan 0:b74591d5ab33 218 return( ret );
be_bryan 0:b74591d5ab33 219 }
be_bryan 0:b74591d5ab33 220
be_bryan 0:b74591d5ab33 221 /*
be_bryan 0:b74591d5ab33 222 * Run through the different sources to add entropy to our accumulator
be_bryan 0:b74591d5ab33 223 */
be_bryan 0:b74591d5ab33 224 static int entropy_gather_internal( mbedtls_entropy_context *ctx )
be_bryan 0:b74591d5ab33 225 {
be_bryan 0:b74591d5ab33 226 int ret, i, have_one_strong = 0;
be_bryan 0:b74591d5ab33 227 unsigned char buf[MBEDTLS_ENTROPY_MAX_GATHER];
be_bryan 0:b74591d5ab33 228 size_t olen;
be_bryan 0:b74591d5ab33 229
be_bryan 0:b74591d5ab33 230 if( ctx->source_count == 0 )
be_bryan 0:b74591d5ab33 231 return( MBEDTLS_ERR_ENTROPY_NO_SOURCES_DEFINED );
be_bryan 0:b74591d5ab33 232
be_bryan 0:b74591d5ab33 233 /*
be_bryan 0:b74591d5ab33 234 * Run through our entropy sources
be_bryan 0:b74591d5ab33 235 */
be_bryan 0:b74591d5ab33 236 for( i = 0; i < ctx->source_count; i++ )
be_bryan 0:b74591d5ab33 237 {
be_bryan 0:b74591d5ab33 238 if( ctx->source[i].strong == MBEDTLS_ENTROPY_SOURCE_STRONG )
be_bryan 0:b74591d5ab33 239 have_one_strong = 1;
be_bryan 0:b74591d5ab33 240
be_bryan 0:b74591d5ab33 241 olen = 0;
be_bryan 0:b74591d5ab33 242 if( ( ret = ctx->source[i].f_source( ctx->source[i].p_source,
be_bryan 0:b74591d5ab33 243 buf, MBEDTLS_ENTROPY_MAX_GATHER, &olen ) ) != 0 )
be_bryan 0:b74591d5ab33 244 {
be_bryan 0:b74591d5ab33 245 return( ret );
be_bryan 0:b74591d5ab33 246 }
be_bryan 0:b74591d5ab33 247
be_bryan 0:b74591d5ab33 248 /*
be_bryan 0:b74591d5ab33 249 * Add if we actually gathered something
be_bryan 0:b74591d5ab33 250 */
be_bryan 0:b74591d5ab33 251 if( olen > 0 )
be_bryan 0:b74591d5ab33 252 {
be_bryan 0:b74591d5ab33 253 entropy_update( ctx, (unsigned char) i, buf, olen );
be_bryan 0:b74591d5ab33 254 ctx->source[i].size += olen;
be_bryan 0:b74591d5ab33 255 }
be_bryan 0:b74591d5ab33 256 }
be_bryan 0:b74591d5ab33 257
be_bryan 0:b74591d5ab33 258 if( have_one_strong == 0 )
be_bryan 0:b74591d5ab33 259 return( MBEDTLS_ERR_ENTROPY_NO_STRONG_SOURCE );
be_bryan 0:b74591d5ab33 260
be_bryan 0:b74591d5ab33 261 return( 0 );
be_bryan 0:b74591d5ab33 262 }
be_bryan 0:b74591d5ab33 263
be_bryan 0:b74591d5ab33 264 /*
be_bryan 0:b74591d5ab33 265 * Thread-safe wrapper for entropy_gather_internal()
be_bryan 0:b74591d5ab33 266 */
be_bryan 0:b74591d5ab33 267 int mbedtls_entropy_gather( mbedtls_entropy_context *ctx )
be_bryan 0:b74591d5ab33 268 {
be_bryan 0:b74591d5ab33 269 int ret;
be_bryan 0:b74591d5ab33 270
be_bryan 0:b74591d5ab33 271 #if defined(MBEDTLS_THREADING_C)
be_bryan 0:b74591d5ab33 272 if( ( ret = mbedtls_mutex_lock( &ctx->mutex ) ) != 0 )
be_bryan 0:b74591d5ab33 273 return( ret );
be_bryan 0:b74591d5ab33 274 #endif
be_bryan 0:b74591d5ab33 275
be_bryan 0:b74591d5ab33 276 ret = entropy_gather_internal( ctx );
be_bryan 0:b74591d5ab33 277
be_bryan 0:b74591d5ab33 278 #if defined(MBEDTLS_THREADING_C)
be_bryan 0:b74591d5ab33 279 if( mbedtls_mutex_unlock( &ctx->mutex ) != 0 )
be_bryan 0:b74591d5ab33 280 return( MBEDTLS_ERR_THREADING_MUTEX_ERROR );
be_bryan 0:b74591d5ab33 281 #endif
be_bryan 0:b74591d5ab33 282
be_bryan 0:b74591d5ab33 283 return( ret );
be_bryan 0:b74591d5ab33 284 }
be_bryan 0:b74591d5ab33 285
be_bryan 0:b74591d5ab33 286 int mbedtls_entropy_func( void *data, unsigned char *output, size_t len )
be_bryan 0:b74591d5ab33 287 {
be_bryan 0:b74591d5ab33 288 int ret, count = 0, i, done;
be_bryan 0:b74591d5ab33 289 mbedtls_entropy_context *ctx = (mbedtls_entropy_context *) data;
be_bryan 0:b74591d5ab33 290 unsigned char buf[MBEDTLS_ENTROPY_BLOCK_SIZE];
be_bryan 0:b74591d5ab33 291
be_bryan 0:b74591d5ab33 292 if( len > MBEDTLS_ENTROPY_BLOCK_SIZE )
be_bryan 0:b74591d5ab33 293 return( MBEDTLS_ERR_ENTROPY_SOURCE_FAILED );
be_bryan 0:b74591d5ab33 294
be_bryan 0:b74591d5ab33 295 #if defined(MBEDTLS_ENTROPY_NV_SEED)
be_bryan 0:b74591d5ab33 296 /* Update the NV entropy seed before generating any entropy for outside
be_bryan 0:b74591d5ab33 297 * use.
be_bryan 0:b74591d5ab33 298 */
be_bryan 0:b74591d5ab33 299 if( ctx->initial_entropy_run == 0 )
be_bryan 0:b74591d5ab33 300 {
be_bryan 0:b74591d5ab33 301 ctx->initial_entropy_run = 1;
be_bryan 0:b74591d5ab33 302 if( ( ret = mbedtls_entropy_update_nv_seed( ctx ) ) != 0 )
be_bryan 0:b74591d5ab33 303 return( ret );
be_bryan 0:b74591d5ab33 304 }
be_bryan 0:b74591d5ab33 305 #endif
be_bryan 0:b74591d5ab33 306
be_bryan 0:b74591d5ab33 307 #if defined(MBEDTLS_THREADING_C)
be_bryan 0:b74591d5ab33 308 if( ( ret = mbedtls_mutex_lock( &ctx->mutex ) ) != 0 )
be_bryan 0:b74591d5ab33 309 return( ret );
be_bryan 0:b74591d5ab33 310 #endif
be_bryan 0:b74591d5ab33 311
be_bryan 0:b74591d5ab33 312 /*
be_bryan 0:b74591d5ab33 313 * Always gather extra entropy before a call
be_bryan 0:b74591d5ab33 314 */
be_bryan 0:b74591d5ab33 315 do
be_bryan 0:b74591d5ab33 316 {
be_bryan 0:b74591d5ab33 317 if( count++ > ENTROPY_MAX_LOOP )
be_bryan 0:b74591d5ab33 318 {
be_bryan 0:b74591d5ab33 319 ret = MBEDTLS_ERR_ENTROPY_SOURCE_FAILED;
be_bryan 0:b74591d5ab33 320 goto exit;
be_bryan 0:b74591d5ab33 321 }
be_bryan 0:b74591d5ab33 322
be_bryan 0:b74591d5ab33 323 if( ( ret = entropy_gather_internal( ctx ) ) != 0 )
be_bryan 0:b74591d5ab33 324 goto exit;
be_bryan 0:b74591d5ab33 325
be_bryan 0:b74591d5ab33 326 done = 1;
be_bryan 0:b74591d5ab33 327 for( i = 0; i < ctx->source_count; i++ )
be_bryan 0:b74591d5ab33 328 if( ctx->source[i].size < ctx->source[i].threshold )
be_bryan 0:b74591d5ab33 329 done = 0;
be_bryan 0:b74591d5ab33 330 }
be_bryan 0:b74591d5ab33 331 while( ! done );
be_bryan 0:b74591d5ab33 332
be_bryan 0:b74591d5ab33 333 memset( buf, 0, MBEDTLS_ENTROPY_BLOCK_SIZE );
be_bryan 0:b74591d5ab33 334
be_bryan 0:b74591d5ab33 335 #if defined(MBEDTLS_ENTROPY_SHA512_ACCUMULATOR)
be_bryan 0:b74591d5ab33 336 mbedtls_sha512_finish( &ctx->accumulator, buf );
be_bryan 0:b74591d5ab33 337
be_bryan 0:b74591d5ab33 338 /*
be_bryan 0:b74591d5ab33 339 * Reset accumulator and counters and recycle existing entropy
be_bryan 0:b74591d5ab33 340 */
be_bryan 0:b74591d5ab33 341 memset( &ctx->accumulator, 0, sizeof( mbedtls_sha512_context ) );
be_bryan 0:b74591d5ab33 342 mbedtls_sha512_starts( &ctx->accumulator, 0 );
be_bryan 0:b74591d5ab33 343 mbedtls_sha512_update( &ctx->accumulator, buf, MBEDTLS_ENTROPY_BLOCK_SIZE );
be_bryan 0:b74591d5ab33 344
be_bryan 0:b74591d5ab33 345 /*
be_bryan 0:b74591d5ab33 346 * Perform second SHA-512 on entropy
be_bryan 0:b74591d5ab33 347 */
be_bryan 0:b74591d5ab33 348 mbedtls_sha512( buf, MBEDTLS_ENTROPY_BLOCK_SIZE, buf, 0 );
be_bryan 0:b74591d5ab33 349 #else /* MBEDTLS_ENTROPY_SHA512_ACCUMULATOR */
be_bryan 0:b74591d5ab33 350 mbedtls_sha256_finish( &ctx->accumulator, buf );
be_bryan 0:b74591d5ab33 351
be_bryan 0:b74591d5ab33 352 /*
be_bryan 0:b74591d5ab33 353 * Reset accumulator and counters and recycle existing entropy
be_bryan 0:b74591d5ab33 354 */
be_bryan 0:b74591d5ab33 355 memset( &ctx->accumulator, 0, sizeof( mbedtls_sha256_context ) );
be_bryan 0:b74591d5ab33 356 mbedtls_sha256_starts( &ctx->accumulator, 0 );
be_bryan 0:b74591d5ab33 357 mbedtls_sha256_update( &ctx->accumulator, buf, MBEDTLS_ENTROPY_BLOCK_SIZE );
be_bryan 0:b74591d5ab33 358
be_bryan 0:b74591d5ab33 359 /*
be_bryan 0:b74591d5ab33 360 * Perform second SHA-256 on entropy
be_bryan 0:b74591d5ab33 361 */
be_bryan 0:b74591d5ab33 362 mbedtls_sha256( buf, MBEDTLS_ENTROPY_BLOCK_SIZE, buf, 0 );
be_bryan 0:b74591d5ab33 363 #endif /* MBEDTLS_ENTROPY_SHA512_ACCUMULATOR */
be_bryan 0:b74591d5ab33 364
be_bryan 0:b74591d5ab33 365 for( i = 0; i < ctx->source_count; i++ )
be_bryan 0:b74591d5ab33 366 ctx->source[i].size = 0;
be_bryan 0:b74591d5ab33 367
be_bryan 0:b74591d5ab33 368 memcpy( output, buf, len );
be_bryan 0:b74591d5ab33 369
be_bryan 0:b74591d5ab33 370 ret = 0;
be_bryan 0:b74591d5ab33 371
be_bryan 0:b74591d5ab33 372 exit:
be_bryan 0:b74591d5ab33 373 #if defined(MBEDTLS_THREADING_C)
be_bryan 0:b74591d5ab33 374 if( mbedtls_mutex_unlock( &ctx->mutex ) != 0 )
be_bryan 0:b74591d5ab33 375 return( MBEDTLS_ERR_THREADING_MUTEX_ERROR );
be_bryan 0:b74591d5ab33 376 #endif
be_bryan 0:b74591d5ab33 377
be_bryan 0:b74591d5ab33 378 return( ret );
be_bryan 0:b74591d5ab33 379 }
be_bryan 0:b74591d5ab33 380
be_bryan 0:b74591d5ab33 381 #if defined(MBEDTLS_ENTROPY_NV_SEED)
be_bryan 0:b74591d5ab33 382 int mbedtls_entropy_update_nv_seed( mbedtls_entropy_context *ctx )
be_bryan 0:b74591d5ab33 383 {
be_bryan 0:b74591d5ab33 384 int ret = MBEDTLS_ERR_ENTROPY_FILE_IO_ERROR;
be_bryan 0:b74591d5ab33 385 unsigned char buf[ MBEDTLS_ENTROPY_MAX_SEED_SIZE ];
be_bryan 0:b74591d5ab33 386
be_bryan 0:b74591d5ab33 387 /* Read new seed and write it to NV */
be_bryan 0:b74591d5ab33 388 if( ( ret = mbedtls_entropy_func( ctx, buf, MBEDTLS_ENTROPY_BLOCK_SIZE ) ) != 0 )
be_bryan 0:b74591d5ab33 389 return( ret );
be_bryan 0:b74591d5ab33 390
be_bryan 0:b74591d5ab33 391 if( mbedtls_nv_seed_write( buf, MBEDTLS_ENTROPY_BLOCK_SIZE ) < 0 )
be_bryan 0:b74591d5ab33 392 return( MBEDTLS_ERR_ENTROPY_FILE_IO_ERROR );
be_bryan 0:b74591d5ab33 393
be_bryan 0:b74591d5ab33 394 /* Manually update the remaining stream with a separator value to diverge */
be_bryan 0:b74591d5ab33 395 memset( buf, 0, MBEDTLS_ENTROPY_BLOCK_SIZE );
be_bryan 0:b74591d5ab33 396 mbedtls_entropy_update_manual( ctx, buf, MBEDTLS_ENTROPY_BLOCK_SIZE );
be_bryan 0:b74591d5ab33 397
be_bryan 0:b74591d5ab33 398 return( 0 );
be_bryan 0:b74591d5ab33 399 }
be_bryan 0:b74591d5ab33 400 #endif /* MBEDTLS_ENTROPY_NV_SEED */
be_bryan 0:b74591d5ab33 401
be_bryan 0:b74591d5ab33 402 #if defined(MBEDTLS_FS_IO)
be_bryan 0:b74591d5ab33 403 int mbedtls_entropy_write_seed_file( mbedtls_entropy_context *ctx, const char *path )
be_bryan 0:b74591d5ab33 404 {
be_bryan 0:b74591d5ab33 405 int ret = MBEDTLS_ERR_ENTROPY_FILE_IO_ERROR;
be_bryan 0:b74591d5ab33 406 FILE *f;
be_bryan 0:b74591d5ab33 407 unsigned char buf[MBEDTLS_ENTROPY_BLOCK_SIZE];
be_bryan 0:b74591d5ab33 408
be_bryan 0:b74591d5ab33 409 if( ( f = fopen( path, "wb" ) ) == NULL )
be_bryan 0:b74591d5ab33 410 return( MBEDTLS_ERR_ENTROPY_FILE_IO_ERROR );
be_bryan 0:b74591d5ab33 411
be_bryan 0:b74591d5ab33 412 if( ( ret = mbedtls_entropy_func( ctx, buf, MBEDTLS_ENTROPY_BLOCK_SIZE ) ) != 0 )
be_bryan 0:b74591d5ab33 413 goto exit;
be_bryan 0:b74591d5ab33 414
be_bryan 0:b74591d5ab33 415 if( fwrite( buf, 1, MBEDTLS_ENTROPY_BLOCK_SIZE, f ) != MBEDTLS_ENTROPY_BLOCK_SIZE )
be_bryan 0:b74591d5ab33 416 {
be_bryan 0:b74591d5ab33 417 ret = MBEDTLS_ERR_ENTROPY_FILE_IO_ERROR;
be_bryan 0:b74591d5ab33 418 goto exit;
be_bryan 0:b74591d5ab33 419 }
be_bryan 0:b74591d5ab33 420
be_bryan 0:b74591d5ab33 421 ret = 0;
be_bryan 0:b74591d5ab33 422
be_bryan 0:b74591d5ab33 423 exit:
be_bryan 0:b74591d5ab33 424 fclose( f );
be_bryan 0:b74591d5ab33 425 return( ret );
be_bryan 0:b74591d5ab33 426 }
be_bryan 0:b74591d5ab33 427
be_bryan 0:b74591d5ab33 428 int mbedtls_entropy_update_seed_file( mbedtls_entropy_context *ctx, const char *path )
be_bryan 0:b74591d5ab33 429 {
be_bryan 0:b74591d5ab33 430 FILE *f;
be_bryan 0:b74591d5ab33 431 size_t n;
be_bryan 0:b74591d5ab33 432 unsigned char buf[ MBEDTLS_ENTROPY_MAX_SEED_SIZE ];
be_bryan 0:b74591d5ab33 433
be_bryan 0:b74591d5ab33 434 if( ( f = fopen( path, "rb" ) ) == NULL )
be_bryan 0:b74591d5ab33 435 return( MBEDTLS_ERR_ENTROPY_FILE_IO_ERROR );
be_bryan 0:b74591d5ab33 436
be_bryan 0:b74591d5ab33 437 fseek( f, 0, SEEK_END );
be_bryan 0:b74591d5ab33 438 n = (size_t) ftell( f );
be_bryan 0:b74591d5ab33 439 fseek( f, 0, SEEK_SET );
be_bryan 0:b74591d5ab33 440
be_bryan 0:b74591d5ab33 441 if( n > MBEDTLS_ENTROPY_MAX_SEED_SIZE )
be_bryan 0:b74591d5ab33 442 n = MBEDTLS_ENTROPY_MAX_SEED_SIZE;
be_bryan 0:b74591d5ab33 443
be_bryan 0:b74591d5ab33 444 if( fread( buf, 1, n, f ) != n )
be_bryan 0:b74591d5ab33 445 {
be_bryan 0:b74591d5ab33 446 fclose( f );
be_bryan 0:b74591d5ab33 447 return( MBEDTLS_ERR_ENTROPY_FILE_IO_ERROR );
be_bryan 0:b74591d5ab33 448 }
be_bryan 0:b74591d5ab33 449
be_bryan 0:b74591d5ab33 450 fclose( f );
be_bryan 0:b74591d5ab33 451
be_bryan 0:b74591d5ab33 452 mbedtls_entropy_update_manual( ctx, buf, n );
be_bryan 0:b74591d5ab33 453
be_bryan 0:b74591d5ab33 454 return( mbedtls_entropy_write_seed_file( ctx, path ) );
be_bryan 0:b74591d5ab33 455 }
be_bryan 0:b74591d5ab33 456 #endif /* MBEDTLS_FS_IO */
be_bryan 0:b74591d5ab33 457
be_bryan 0:b74591d5ab33 458 #if defined(MBEDTLS_SELF_TEST)
be_bryan 0:b74591d5ab33 459 #if !defined(MBEDTLS_TEST_NULL_ENTROPY)
be_bryan 0:b74591d5ab33 460 /*
be_bryan 0:b74591d5ab33 461 * Dummy source function
be_bryan 0:b74591d5ab33 462 */
be_bryan 0:b74591d5ab33 463 static int entropy_dummy_source( void *data, unsigned char *output,
be_bryan 0:b74591d5ab33 464 size_t len, size_t *olen )
be_bryan 0:b74591d5ab33 465 {
be_bryan 0:b74591d5ab33 466 ((void) data);
be_bryan 0:b74591d5ab33 467
be_bryan 0:b74591d5ab33 468 memset( output, 0x2a, len );
be_bryan 0:b74591d5ab33 469 *olen = len;
be_bryan 0:b74591d5ab33 470
be_bryan 0:b74591d5ab33 471 return( 0 );
be_bryan 0:b74591d5ab33 472 }
be_bryan 0:b74591d5ab33 473 #endif /* !MBEDTLS_TEST_NULL_ENTROPY */
be_bryan 0:b74591d5ab33 474
be_bryan 0:b74591d5ab33 475 #if defined(MBEDTLS_ENTROPY_HARDWARE_ALT)
be_bryan 0:b74591d5ab33 476
be_bryan 0:b74591d5ab33 477 static int mbedtls_entropy_source_self_test_gather( unsigned char *buf, size_t buf_len )
be_bryan 0:b74591d5ab33 478 {
be_bryan 0:b74591d5ab33 479 int ret = 0;
be_bryan 0:b74591d5ab33 480 size_t entropy_len = 0;
be_bryan 0:b74591d5ab33 481 size_t olen = 0;
be_bryan 0:b74591d5ab33 482 size_t attempts = buf_len;
be_bryan 0:b74591d5ab33 483
be_bryan 0:b74591d5ab33 484 while( attempts > 0 && entropy_len < buf_len )
be_bryan 0:b74591d5ab33 485 {
be_bryan 0:b74591d5ab33 486 if( ( ret = mbedtls_hardware_poll( NULL, buf + entropy_len,
be_bryan 0:b74591d5ab33 487 buf_len - entropy_len, &olen ) ) != 0 )
be_bryan 0:b74591d5ab33 488 return( ret );
be_bryan 0:b74591d5ab33 489
be_bryan 0:b74591d5ab33 490 entropy_len += olen;
be_bryan 0:b74591d5ab33 491 attempts--;
be_bryan 0:b74591d5ab33 492 }
be_bryan 0:b74591d5ab33 493
be_bryan 0:b74591d5ab33 494 if( entropy_len < buf_len )
be_bryan 0:b74591d5ab33 495 {
be_bryan 0:b74591d5ab33 496 ret = 1;
be_bryan 0:b74591d5ab33 497 }
be_bryan 0:b74591d5ab33 498
be_bryan 0:b74591d5ab33 499 return( ret );
be_bryan 0:b74591d5ab33 500 }
be_bryan 0:b74591d5ab33 501
be_bryan 0:b74591d5ab33 502
be_bryan 0:b74591d5ab33 503 static int mbedtls_entropy_source_self_test_check_bits( const unsigned char *buf,
be_bryan 0:b74591d5ab33 504 size_t buf_len )
be_bryan 0:b74591d5ab33 505 {
be_bryan 0:b74591d5ab33 506 unsigned char set= 0xFF;
be_bryan 0:b74591d5ab33 507 unsigned char unset = 0x00;
be_bryan 0:b74591d5ab33 508 size_t i;
be_bryan 0:b74591d5ab33 509
be_bryan 0:b74591d5ab33 510 for( i = 0; i < buf_len; i++ )
be_bryan 0:b74591d5ab33 511 {
be_bryan 0:b74591d5ab33 512 set &= buf[i];
be_bryan 0:b74591d5ab33 513 unset |= buf[i];
be_bryan 0:b74591d5ab33 514 }
be_bryan 0:b74591d5ab33 515
be_bryan 0:b74591d5ab33 516 return( set == 0xFF || unset == 0x00 );
be_bryan 0:b74591d5ab33 517 }
be_bryan 0:b74591d5ab33 518
be_bryan 0:b74591d5ab33 519 /*
be_bryan 0:b74591d5ab33 520 * A test to ensure hat the entropy sources are functioning correctly
be_bryan 0:b74591d5ab33 521 * and there is no obvious failure. The test performs the following checks:
be_bryan 0:b74591d5ab33 522 * - The entropy source is not providing only 0s (all bits unset) or 1s (all
be_bryan 0:b74591d5ab33 523 * bits set).
be_bryan 0:b74591d5ab33 524 * - The entropy source is not providing values in a pattern. Because the
be_bryan 0:b74591d5ab33 525 * hardware could be providing data in an arbitrary length, this check polls
be_bryan 0:b74591d5ab33 526 * the hardware entropy source twice and compares the result to ensure they
be_bryan 0:b74591d5ab33 527 * are not equal.
be_bryan 0:b74591d5ab33 528 * - The error code returned by the entropy source is not an error.
be_bryan 0:b74591d5ab33 529 */
be_bryan 0:b74591d5ab33 530 int mbedtls_entropy_source_self_test( int verbose )
be_bryan 0:b74591d5ab33 531 {
be_bryan 0:b74591d5ab33 532 int ret = 0;
be_bryan 0:b74591d5ab33 533 unsigned char buf0[2 * sizeof( unsigned long long int )];
be_bryan 0:b74591d5ab33 534 unsigned char buf1[2 * sizeof( unsigned long long int )];
be_bryan 0:b74591d5ab33 535
be_bryan 0:b74591d5ab33 536 if( verbose != 0 )
be_bryan 0:b74591d5ab33 537 mbedtls_printf( " ENTROPY_BIAS test: " );
be_bryan 0:b74591d5ab33 538
be_bryan 0:b74591d5ab33 539 memset( buf0, 0x00, sizeof( buf0 ) );
be_bryan 0:b74591d5ab33 540 memset( buf1, 0x00, sizeof( buf1 ) );
be_bryan 0:b74591d5ab33 541
be_bryan 0:b74591d5ab33 542 if( ( ret = mbedtls_entropy_source_self_test_gather( buf0, sizeof( buf0 ) ) ) != 0 )
be_bryan 0:b74591d5ab33 543 goto cleanup;
be_bryan 0:b74591d5ab33 544 if( ( ret = mbedtls_entropy_source_self_test_gather( buf1, sizeof( buf1 ) ) ) != 0 )
be_bryan 0:b74591d5ab33 545 goto cleanup;
be_bryan 0:b74591d5ab33 546
be_bryan 0:b74591d5ab33 547 /* Make sure that the returned values are not all 0 or 1 */
be_bryan 0:b74591d5ab33 548 if( ( ret = mbedtls_entropy_source_self_test_check_bits( buf0, sizeof( buf0 ) ) ) != 0 )
be_bryan 0:b74591d5ab33 549 goto cleanup;
be_bryan 0:b74591d5ab33 550 if( ( ret = mbedtls_entropy_source_self_test_check_bits( buf1, sizeof( buf1 ) ) ) != 0 )
be_bryan 0:b74591d5ab33 551 goto cleanup;
be_bryan 0:b74591d5ab33 552
be_bryan 0:b74591d5ab33 553 /* Make sure that the entropy source is not returning values in a
be_bryan 0:b74591d5ab33 554 * pattern */
be_bryan 0:b74591d5ab33 555 ret = memcmp( buf0, buf1, sizeof( buf0 ) ) == 0;
be_bryan 0:b74591d5ab33 556
be_bryan 0:b74591d5ab33 557 cleanup:
be_bryan 0:b74591d5ab33 558 if( verbose != 0 )
be_bryan 0:b74591d5ab33 559 {
be_bryan 0:b74591d5ab33 560 if( ret != 0 )
be_bryan 0:b74591d5ab33 561 mbedtls_printf( "failed\n" );
be_bryan 0:b74591d5ab33 562 else
be_bryan 0:b74591d5ab33 563 mbedtls_printf( "passed\n" );
be_bryan 0:b74591d5ab33 564
be_bryan 0:b74591d5ab33 565 mbedtls_printf( "\n" );
be_bryan 0:b74591d5ab33 566 }
be_bryan 0:b74591d5ab33 567
be_bryan 0:b74591d5ab33 568 return( ret != 0 );
be_bryan 0:b74591d5ab33 569 }
be_bryan 0:b74591d5ab33 570
be_bryan 0:b74591d5ab33 571 #endif /* MBEDTLS_ENTROPY_HARDWARE_ALT */
be_bryan 0:b74591d5ab33 572
be_bryan 0:b74591d5ab33 573 /*
be_bryan 0:b74591d5ab33 574 * The actual entropy quality is hard to test, but we can at least
be_bryan 0:b74591d5ab33 575 * test that the functions don't cause errors and write the correct
be_bryan 0:b74591d5ab33 576 * amount of data to buffers.
be_bryan 0:b74591d5ab33 577 */
be_bryan 0:b74591d5ab33 578 int mbedtls_entropy_self_test( int verbose )
be_bryan 0:b74591d5ab33 579 {
be_bryan 0:b74591d5ab33 580 int ret = 1;
be_bryan 0:b74591d5ab33 581 #if !defined(MBEDTLS_TEST_NULL_ENTROPY)
be_bryan 0:b74591d5ab33 582 mbedtls_entropy_context ctx;
be_bryan 0:b74591d5ab33 583 unsigned char buf[MBEDTLS_ENTROPY_BLOCK_SIZE] = { 0 };
be_bryan 0:b74591d5ab33 584 unsigned char acc[MBEDTLS_ENTROPY_BLOCK_SIZE] = { 0 };
be_bryan 0:b74591d5ab33 585 size_t i, j;
be_bryan 0:b74591d5ab33 586 #endif /* !MBEDTLS_TEST_NULL_ENTROPY */
be_bryan 0:b74591d5ab33 587
be_bryan 0:b74591d5ab33 588 if( verbose != 0 )
be_bryan 0:b74591d5ab33 589 mbedtls_printf( " ENTROPY test: " );
be_bryan 0:b74591d5ab33 590
be_bryan 0:b74591d5ab33 591 #if !defined(MBEDTLS_TEST_NULL_ENTROPY)
be_bryan 0:b74591d5ab33 592 mbedtls_entropy_init( &ctx );
be_bryan 0:b74591d5ab33 593
be_bryan 0:b74591d5ab33 594 /* First do a gather to make sure we have default sources */
be_bryan 0:b74591d5ab33 595 if( ( ret = mbedtls_entropy_gather( &ctx ) ) != 0 )
be_bryan 0:b74591d5ab33 596 goto cleanup;
be_bryan 0:b74591d5ab33 597
be_bryan 0:b74591d5ab33 598 ret = mbedtls_entropy_add_source( &ctx, entropy_dummy_source, NULL, 16,
be_bryan 0:b74591d5ab33 599 MBEDTLS_ENTROPY_SOURCE_WEAK );
be_bryan 0:b74591d5ab33 600 if( ret != 0 )
be_bryan 0:b74591d5ab33 601 goto cleanup;
be_bryan 0:b74591d5ab33 602
be_bryan 0:b74591d5ab33 603 if( ( ret = mbedtls_entropy_update_manual( &ctx, buf, sizeof buf ) ) != 0 )
be_bryan 0:b74591d5ab33 604 goto cleanup;
be_bryan 0:b74591d5ab33 605
be_bryan 0:b74591d5ab33 606 /*
be_bryan 0:b74591d5ab33 607 * To test that mbedtls_entropy_func writes correct number of bytes:
be_bryan 0:b74591d5ab33 608 * - use the whole buffer and rely on ASan to detect overruns
be_bryan 0:b74591d5ab33 609 * - collect entropy 8 times and OR the result in an accumulator:
be_bryan 0:b74591d5ab33 610 * any byte should then be 0 with probably 2^(-64), so requiring
be_bryan 0:b74591d5ab33 611 * each of the 32 or 64 bytes to be non-zero has a false failure rate
be_bryan 0:b74591d5ab33 612 * of at most 2^(-58) which is acceptable.
be_bryan 0:b74591d5ab33 613 */
be_bryan 0:b74591d5ab33 614 for( i = 0; i < 8; i++ )
be_bryan 0:b74591d5ab33 615 {
be_bryan 0:b74591d5ab33 616 if( ( ret = mbedtls_entropy_func( &ctx, buf, sizeof( buf ) ) ) != 0 )
be_bryan 0:b74591d5ab33 617 goto cleanup;
be_bryan 0:b74591d5ab33 618
be_bryan 0:b74591d5ab33 619 for( j = 0; j < sizeof( buf ); j++ )
be_bryan 0:b74591d5ab33 620 acc[j] |= buf[j];
be_bryan 0:b74591d5ab33 621 }
be_bryan 0:b74591d5ab33 622
be_bryan 0:b74591d5ab33 623 for( j = 0; j < sizeof( buf ); j++ )
be_bryan 0:b74591d5ab33 624 {
be_bryan 0:b74591d5ab33 625 if( acc[j] == 0 )
be_bryan 0:b74591d5ab33 626 {
be_bryan 0:b74591d5ab33 627 ret = 1;
be_bryan 0:b74591d5ab33 628 goto cleanup;
be_bryan 0:b74591d5ab33 629 }
be_bryan 0:b74591d5ab33 630 }
be_bryan 0:b74591d5ab33 631
be_bryan 0:b74591d5ab33 632 #if defined(MBEDTLS_ENTROPY_HARDWARE_ALT)
be_bryan 0:b74591d5ab33 633 if( ( ret = mbedtls_entropy_source_self_test( 0 ) ) != 0 )
be_bryan 0:b74591d5ab33 634 goto cleanup;
be_bryan 0:b74591d5ab33 635 #endif
be_bryan 0:b74591d5ab33 636
be_bryan 0:b74591d5ab33 637 cleanup:
be_bryan 0:b74591d5ab33 638 mbedtls_entropy_free( &ctx );
be_bryan 0:b74591d5ab33 639 #endif /* !MBEDTLS_TEST_NULL_ENTROPY */
be_bryan 0:b74591d5ab33 640
be_bryan 0:b74591d5ab33 641 if( verbose != 0 )
be_bryan 0:b74591d5ab33 642 {
be_bryan 0:b74591d5ab33 643 if( ret != 0 )
be_bryan 0:b74591d5ab33 644 mbedtls_printf( "failed\n" );
be_bryan 0:b74591d5ab33 645 else
be_bryan 0:b74591d5ab33 646 mbedtls_printf( "passed\n" );
be_bryan 0:b74591d5ab33 647
be_bryan 0:b74591d5ab33 648 mbedtls_printf( "\n" );
be_bryan 0:b74591d5ab33 649 }
be_bryan 0:b74591d5ab33 650
be_bryan 0:b74591d5ab33 651 return( ret != 0 );
be_bryan 0:b74591d5ab33 652 }
be_bryan 0:b74591d5ab33 653 #endif /* MBEDTLS_SELF_TEST */
be_bryan 0:b74591d5ab33 654
be_bryan 0:b74591d5ab33 655 #endif /* MBEDTLS_ENTROPY_C */