BA / Mbed OS BaBoRo_test2
Committer:
borlanic
Date:
Tue Apr 24 11:45:18 2018 +0000
Revision:
0:02dd72d1d465
BaBoRo_test2 - backup 1

Who changed what in which revision?

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