예제 #1
0
int mbedtls_entropy_func(void *data, unsigned char *output, size_t len)
{
	int ret, count = 0, i, done;
	mbedtls_entropy_context *ctx = (mbedtls_entropy_context *)data;
	unsigned char buf[MBEDTLS_ENTROPY_BLOCK_SIZE];

	if (len > MBEDTLS_ENTROPY_BLOCK_SIZE) {
		return (MBEDTLS_ERR_ENTROPY_SOURCE_FAILED);
	}
#if defined(MBEDTLS_ENTROPY_NV_SEED)
	/* Update the NV entropy seed before generating any entropy for outside
	 * use.
	 */
	if (ctx->initial_entropy_run == 0) {
		ctx->initial_entropy_run = 1;
		if ((ret = mbedtls_entropy_update_nv_seed(ctx)) != 0) {
			return (ret);
		}
	}
#endif

#if defined(MBEDTLS_THREADING_C)
	if ((ret = mbedtls_mutex_lock(&ctx->mutex)) != 0) {
		return (ret);
	}
#endif

	/*
	 * Always gather extra entropy before a call
	 */
	do {
		if (count++ > ENTROPY_MAX_LOOP) {
			ret = MBEDTLS_ERR_ENTROPY_SOURCE_FAILED;
			goto exit;
		}

		if ((ret = entropy_gather_internal(ctx)) != 0) {
			goto exit;
		}

		done = 1;
		for (i = 0; i < ctx->source_count; i++)
			if (ctx->source[i].size < ctx->source[i].threshold) {
				done = 0;
			}
	} while (!done);

	memset(buf, 0, MBEDTLS_ENTROPY_BLOCK_SIZE);

#if defined(MBEDTLS_ENTROPY_SHA512_ACCUMULATOR)
	mbedtls_sha512_finish(&ctx->accumulator, buf);

	/*
	 * Reset accumulator and counters and recycle existing entropy
	 */
	memset(&ctx->accumulator, 0, sizeof(mbedtls_sha512_context));
	mbedtls_sha512_starts(&ctx->accumulator, 0);
	mbedtls_sha512_update(&ctx->accumulator, buf, MBEDTLS_ENTROPY_BLOCK_SIZE);

	/*
	 * Perform second SHA-512 on entropy
	 */
	mbedtls_sha512(buf, MBEDTLS_ENTROPY_BLOCK_SIZE, buf, 0);
#else							/* MBEDTLS_ENTROPY_SHA512_ACCUMULATOR */
	mbedtls_sha256_finish(&ctx->accumulator, buf);

	/*
	 * Reset accumulator and counters and recycle existing entropy
	 */
	memset(&ctx->accumulator, 0, sizeof(mbedtls_sha256_context));
	mbedtls_sha256_starts(&ctx->accumulator, 0);
	mbedtls_sha256_update(&ctx->accumulator, buf, MBEDTLS_ENTROPY_BLOCK_SIZE);

	/*
	 * Perform second SHA-256 on entropy
	 */
	mbedtls_sha256(buf, MBEDTLS_ENTROPY_BLOCK_SIZE, buf, 0);
#endif							/* MBEDTLS_ENTROPY_SHA512_ACCUMULATOR */

	for (i = 0; i < ctx->source_count; i++) {
		ctx->source[i].size = 0;
	}

	memcpy(output, buf, len);

	ret = 0;

exit:
#if defined(MBEDTLS_THREADING_C)
	if (mbedtls_mutex_unlock(&ctx->mutex) != 0) {
		return (MBEDTLS_ERR_THREADING_MUTEX_ERROR);
	}
#endif

	return (ret);
}
예제 #2
0
파일: entropy.c 프로젝트: sanikoyes/tools
static int l_mbedtls_entropy_update_nv_seed(lua_State *L) {

	mbedtls_entropy_context *ctx = (mbedtls_entropy_context *) luaL_checkudata(L, 1, CLASS_NAME);
	lua_pushinteger(L, mbedtls_entropy_update_nv_seed(ctx));
	return 1;
}
예제 #3
0
파일: entropy.c 프로젝트: Moteesh/reactos
int mbedtls_entropy_func( void *data, unsigned char *output, size_t len )
{
    int ret, count = 0, i, done;
    mbedtls_entropy_context *ctx = (mbedtls_entropy_context *) data;
    unsigned char buf[MBEDTLS_ENTROPY_BLOCK_SIZE];

    if( len > MBEDTLS_ENTROPY_BLOCK_SIZE )
        return( MBEDTLS_ERR_ENTROPY_SOURCE_FAILED );

#if defined(MBEDTLS_ENTROPY_NV_SEED)
    /* Update the NV entropy seed before generating any entropy for outside
     * use.
     */
    if( ctx->initial_entropy_run == 0 )
    {
        ctx->initial_entropy_run = 1;
        if( ( ret = mbedtls_entropy_update_nv_seed( ctx ) ) != 0 )
            return( ret );
    }
#endif

#if defined(MBEDTLS_THREADING_C)
    if( ( ret = mbedtls_mutex_lock( &ctx->mutex ) ) != 0 )
        return( ret );
#endif

    /*
     * Always gather extra entropy before a call
     */
    do
    {
        if( count++ > ENTROPY_MAX_LOOP )
        {
            ret = MBEDTLS_ERR_ENTROPY_SOURCE_FAILED;
            goto exit;
        }

        if( ( ret = entropy_gather_internal( ctx ) ) != 0 )
            goto exit;

        done = 1;
        for( i = 0; i < ctx->source_count; i++ )
            if( ctx->source[i].size < ctx->source[i].threshold )
                done = 0;
    }
    while( ! done );

    memset( buf, 0, MBEDTLS_ENTROPY_BLOCK_SIZE );

#if defined(MBEDTLS_ENTROPY_SHA512_ACCUMULATOR)
    /*
     * Note that at this stage it is assumed that the accumulator was started
     * in a previous call to entropy_update(). If this is not guaranteed, the
     * code below will fail.
     */
    if( ( ret = mbedtls_sha512_finish_ret( &ctx->accumulator, buf ) ) != 0 )
        goto exit;

    /*
     * Reset accumulator and counters and recycle existing entropy
     */
    mbedtls_sha512_free( &ctx->accumulator );
    mbedtls_sha512_init( &ctx->accumulator );
    if( ( ret = mbedtls_sha512_starts_ret( &ctx->accumulator, 0 ) ) != 0 )
        goto exit;
    if( ( ret = mbedtls_sha512_update_ret( &ctx->accumulator, buf,
                                           MBEDTLS_ENTROPY_BLOCK_SIZE ) ) != 0 )
        goto exit;

    /*
     * Perform second SHA-512 on entropy
     */
    if( ( ret = mbedtls_sha512_ret( buf, MBEDTLS_ENTROPY_BLOCK_SIZE,
                                    buf, 0 ) ) != 0 )
        goto exit;
#else /* MBEDTLS_ENTROPY_SHA512_ACCUMULATOR */
    if( ( ret = mbedtls_sha256_finish_ret( &ctx->accumulator, buf ) ) != 0 )
        goto exit;

    /*
     * Reset accumulator and counters and recycle existing entropy
     */
    mbedtls_sha256_free( &ctx->accumulator );
    mbedtls_sha256_init( &ctx->accumulator );
    if( ( ret = mbedtls_sha256_starts_ret( &ctx->accumulator, 0 ) ) != 0 )
        goto exit;
    if( ( ret = mbedtls_sha256_update_ret( &ctx->accumulator, buf,
                                           MBEDTLS_ENTROPY_BLOCK_SIZE ) ) != 0 )
        goto exit;

    /*
     * Perform second SHA-256 on entropy
     */
    if( ( ret = mbedtls_sha256_ret( buf, MBEDTLS_ENTROPY_BLOCK_SIZE,
                                    buf, 0 ) ) != 0 )
        goto exit;
#endif /* MBEDTLS_ENTROPY_SHA512_ACCUMULATOR */

    for( i = 0; i < ctx->source_count; i++ )
        ctx->source[i].size = 0;

    memcpy( output, buf, len );

    ret = 0;

exit:
    mbedtls_zeroize( buf, sizeof( buf ) );

#if defined(MBEDTLS_THREADING_C)
    if( mbedtls_mutex_unlock( &ctx->mutex ) != 0 )
        return( MBEDTLS_ERR_THREADING_MUTEX_ERROR );
#endif

    return( ret );
}