int yarrow256_update(struct yarrow256_ctx *ctx, unsigned source_index, unsigned entropy, size_t length, const uint8_t *data) { enum yarrow_pool_id current; struct yarrow_source *source; assert(source_index < ctx->nsources); if (!length) /* Nothing happens */ return 0; source = &ctx->sources[source_index]; if (!ctx->seeded) /* While seeding, use the slow pool */ current = YARROW_SLOW; else { current = source->next; source->next = !source->next; } sha256_update(&ctx->pools[current], length, data); /* NOTE: We should be careful to avoid overflows in the estimates. */ if (source->estimate[current] < YARROW_MAX_ENTROPY) { if (entropy > YARROW_MAX_ENTROPY) entropy = YARROW_MAX_ENTROPY; if ( (length < (YARROW_MAX_ENTROPY / YARROW_MULTIPLIER)) && (entropy > YARROW_MULTIPLIER * length) ) entropy = YARROW_MULTIPLIER * length; entropy += source->estimate[current]; if (entropy > YARROW_MAX_ENTROPY) entropy = YARROW_MAX_ENTROPY; source->estimate[current] = entropy; } /* Check for seed/reseed */ switch(current) { case YARROW_FAST: #if YARROW_DEBUG fprintf(stderr, "yarrow256_update: source_index = %d,\n" " fast pool estimate = %d\n", source_index, source->estimate[YARROW_FAST]); #endif if (source->estimate[YARROW_FAST] >= YARROW_FAST_THRESHOLD) { yarrow256_fast_reseed(ctx); return 1; } else return 0; case YARROW_SLOW: { if (!yarrow256_needed_sources(ctx)) { yarrow256_slow_reseed(ctx); return 1; } else return 0; } default: abort(); } }
int yarrow256_update(struct yarrow256_ctx *ctx, unsigned source_index, unsigned entropy, unsigned length, const quint8 *data) { enum yarrow_pool_id current; struct yarrow_source *source; assert(source_index < ctx->nsources); if (!length) /* Nothing happens */ return 0; source = &ctx->sources[source_index]; if (!ctx->seeded) /* While seeding, use the slow pool */ current = YARROW_SLOW; else { current = source->next; source->next = (yarrow_pool_id)!source->next; } sha256_update(&ctx->pools[current],data,length); /* NOTE: We should be careful to avoid overflows in the estimates. */ if (source->estimate[current] < YARROW_MAX_ENTROPY) { if (entropy > YARROW_MAX_ENTROPY) entropy = YARROW_MAX_ENTROPY; if ( (length < (YARROW_MAX_ENTROPY / YARROW_MULTIPLIER)) && (entropy > YARROW_MULTIPLIER * length) ) entropy = YARROW_MULTIPLIER * length; /* FIXME: Calling a more sophisticated estimater should be done * here. */ entropy += source->estimate[current]; if (entropy > YARROW_MAX_ENTROPY) entropy = YARROW_MAX_ENTROPY; source->estimate[current] = entropy; } /* Check for seed/reseed */ switch(current) { case YARROW_FAST: #if YARROW_DEBUG fprintf(stderr, "yarrow256_update: source_index = %d,\n" " fast pool estimate = %d\n", source_index, source->estimate[YARROW_FAST]); #endif if (source->estimate[YARROW_FAST] >= YARROW_FAST_THRESHOLD) { yarrow_fast_reseed(ctx); return 1; } else return 0; case YARROW_SLOW: { /* FIXME: This is somewhat inefficient. It would be better to * either maintain the count, or do this loop only if the * current source just crossed the threshold. */ if (!yarrow256_needed_sources(ctx)) { yarrow_slow_reseed(ctx); ctx->seeded = 1; return 1; } else return 0; } default: abort(); } }