BBR 1 Ebene

Committer:
borlanic
Date:
Mon May 14 11:29:06 2018 +0000
Revision:
0:fbdae7e6d805
BBR

Who changed what in which revision?

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