예제 #1
0
void ctr_drbg_update( ctr_drbg_context *ctx,
                      const unsigned char *additional, size_t add_len )
{
    unsigned char add_input[CTR_DRBG_SEEDLEN];

    if( add_len > 0 )
    {
        block_cipher_df( add_input, additional, add_len );
        ctr_drbg_update_internal( ctx, add_input );
    }
}
예제 #2
0
void mbedtls_ctr_drbg_update( mbedtls_ctr_drbg_context *ctx,
                      const unsigned char *additional, size_t add_len )
{
    unsigned char add_input[MBEDTLS_CTR_DRBG_SEEDLEN];

    if( add_len > 0 )
    {
        /* MAX_INPUT would be more logical here, but we have to match
         * block_cipher_df()'s limits since we can't propagate errors */
        if( add_len > MBEDTLS_CTR_DRBG_MAX_SEED_INPUT )
            add_len = MBEDTLS_CTR_DRBG_MAX_SEED_INPUT;

        block_cipher_df( add_input, additional, add_len );
        ctr_drbg_update_internal( ctx, add_input );
    }
}
예제 #3
0
/*
 * Reseeds the CTR_DRBG instance with entropy.  entropy_len_bits must
 * be exactly 256.
 */
enum ctr_drbg_status_t ctr_drbg_reseed(struct ctr_drbg_ctx_s *ctx,
					const void     *entropy,
					size_t         entropy_len_bits)
{
	enum ctr_drbg_status_t update_rv;
	uint8_t           seed_material[32];
	int               rc;

	if (ctx == NULL || entropy == NULL)
		return CTR_DRBG_INVALID_ARG;

	update_rv = block_cipher_df(ctx,
				(uint8_t *)entropy,
				(entropy_len_bits / 8),
				seed_material,
				32
				);
	if (CTR_DRBG_SUCCESS != update_rv) {
		memset(seed_material, 0, 32);
		return CTR_DRBG_GENERAL_ERROR;
	}

	rc = crypto_ablkcipher_setkey(ctx->aes_ctx.tfm,
				ctx->seed.key_V.key,
				AES128_KEY_SIZE
				);
	if (rc) {
		memset(seed_material, 0, 32);
		pr_debug("set-key in Instantiate failed, returns with %d", rc);
		return CTR_DRBG_GENERAL_ERROR;
	}

	pr_debug("ctr_drbg_reseed, to call update\n");
	update_rv = update(ctx, (const uint8_t *)seed_material, 32);
	pr_debug("ctr_drbg_reseed, after called update\n");
	if (update_rv != CTR_DRBG_SUCCESS) {
		memset(seed_material, 0, 32);
		return update_rv;
	}
	ctx->reseed_counter = 1;  /* think 0 but SP 800-90 says 1 */

	memset(seed_material, 0, 32);

	return CTR_DRBG_SUCCESS;

}
예제 #4
0
파일: ctr_drbg.c 프로젝트: ncbi/ncbi-vdb
int vdb_mbedtls_ctr_drbg_reseed( mbedtls_ctr_drbg_context *ctx,
                     const unsigned char *additional, size_t len )
{
    unsigned char seed[MBEDTLS_CTR_DRBG_MAX_SEED_INPUT];
    size_t seedlen = 0;

    if( ctx->entropy_len > MBEDTLS_CTR_DRBG_MAX_SEED_INPUT ||
        len > MBEDTLS_CTR_DRBG_MAX_SEED_INPUT - ctx->entropy_len )
        return( MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG );

    memset( seed, 0, MBEDTLS_CTR_DRBG_MAX_SEED_INPUT );

    /*
     * Gather entropy_len bytes of entropy to seed state
     */
    if( 0 != ctx->f_entropy( ctx->p_entropy, seed,
                             ctx->entropy_len ) )
    {
        return( MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED );
    }

    seedlen += ctx->entropy_len;

    /*
     * Add additional data
     */
    if( additional && len )
    {
        memcpy( seed + seedlen, additional, len );
        seedlen += len;
    }

    /*
     * Reduce to 384 bits
     */
    block_cipher_df( seed, seed, seedlen );

    /*
     * Update state
     */
    ctr_drbg_update_internal( ctx, seed );
    ctx->reseed_counter = 1;

    return( 0 );
}
예제 #5
0
int mbedtls_ctr_drbg_random_with_add( void *p_rng,
                              unsigned char *output, size_t output_len,
                              const unsigned char *additional, size_t add_len )
{
    int ret = 0;
    mbedtls_ctr_drbg_context *ctx = (mbedtls_ctr_drbg_context *) p_rng;
    unsigned char add_input[MBEDTLS_CTR_DRBG_SEEDLEN];
    unsigned char *p = output;
    unsigned char tmp[MBEDTLS_CTR_DRBG_BLOCKSIZE];
    int i;
    size_t use_len;

    if( output_len > MBEDTLS_CTR_DRBG_MAX_REQUEST )
        return( MBEDTLS_ERR_CTR_DRBG_REQUEST_TOO_BIG );

    if( add_len > MBEDTLS_CTR_DRBG_MAX_INPUT )
        return( MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG );

    memset( add_input, 0, MBEDTLS_CTR_DRBG_SEEDLEN );

    if( ctx->reseed_counter > ctx->reseed_interval ||
        ctx->prediction_resistance )
    {
        if( ( ret = mbedtls_ctr_drbg_reseed( ctx, additional, add_len ) ) != 0 )
            return( ret );

        add_len = 0;
    }

    if( add_len > 0 )
    {
        block_cipher_df( add_input, additional, add_len );
        ctr_drbg_update_internal( ctx, add_input );
    }

    while( output_len > 0 )
    {
        /*
         * Increase counter
         */
        for( i = MBEDTLS_CTR_DRBG_BLOCKSIZE; i > 0; i-- )
            if( ++ctx->counter[i - 1] != 0 )
                break;

        /*
         * Crypt counter block
         */
        mbedtls_aes_crypt_ecb( &ctx->aes_ctx, MBEDTLS_AES_ENCRYPT, ctx->counter, tmp );

        use_len = ( output_len > MBEDTLS_CTR_DRBG_BLOCKSIZE ) ? MBEDTLS_CTR_DRBG_BLOCKSIZE :
                                                       output_len;
        /*
         * Copy random block to destination
         */
        memcpy( p, tmp, use_len );
        p += use_len;
        output_len -= use_len;
    }

    ctr_drbg_update_internal( ctx, add_input );

    ctx->reseed_counter++;

    return( 0 );
}
예제 #6
0
int ctr_drbg_random_with_add( void *p_rng,
                              unsigned char *output, size_t output_len,
                              const unsigned char *additional, size_t add_len )
{
    int ret = 0;
    ctr_drbg_context *ctx = (ctr_drbg_context *) p_rng;
    unsigned char add_input[CTR_DRBG_SEEDLEN];
    unsigned char *p = output;
    unsigned char tmp[CTR_DRBG_BLOCKSIZE];
    int cb, i;
    size_t use_len;

    if( output_len > CTR_DRBG_MAX_REQUEST )
        return( POLARSSL_ERR_CTR_DRBG_REQUEST_TOO_BIG );

    if( add_len > CTR_DRBG_MAX_INPUT )
        return( POLARSSL_ERR_CTR_DRBG_INPUT_TOO_BIG );

    memset( add_input, 0, CTR_DRBG_SEEDLEN );

    if( ctx->reseed_counter > ctx->reseed_interval ||
        ctx->prediction_resistance )
    {
        if( ( ret = ctr_drbg_reseed( ctx, additional, add_len ) ) != 0 )
            return( ret );

        add_len = 0;
    }

    if( add_len > 0 )
    {
        block_cipher_df( add_input, additional, add_len );
        ctr_drbg_update_internal( ctx, add_input );
    }

    while( output_len > 0 )
    {
        /*
         * Increase counter
         */
        i = CTR_DRBG_BLOCKSIZE - 1;
        do {
            ctx->counter[i]++;
            cb = ctx->counter[i] == 0;
        } while( i-- && cb );

        /*
         * Crypt counter block
         */
        aes_crypt_ecb( &ctx->aes_ctx, AES_ENCRYPT, ctx->counter, tmp );

        use_len = (output_len > CTR_DRBG_BLOCKSIZE ) ? CTR_DRBG_BLOCKSIZE : output_len;
        /*
         * Copy random block to destination
         */
        memcpy( p, tmp, use_len );
        p += use_len;
        output_len -= use_len;
    }

    ctr_drbg_update_internal( ctx, add_input );

    ctx->reseed_counter++;

    return( 0 );
}
예제 #7
0
enum ctr_drbg_status_t
ctr_drbg_instantiate(struct ctr_drbg_ctx_s *ctx,
			const uint8_t *entropy,
			size_t entropy_len_bits,
			const uint8_t *nonce,
			size_t nonce_len_bits,
			unsigned long long reseed_interval)
{

	enum ctr_drbg_status_t update_rv;
	uint8_t           seed_material[32];
	uint8_t           df_input[32];
	int               rc;

	if (ctx == NULL || entropy == NULL || nonce == NULL)
		return CTR_DRBG_INVALID_ARG;
	if (((nonce_len_bits / 8) + (entropy_len_bits / 8)) > 32) {
		pr_info("\nentropy_len_bits + nonce_len_bits is too long!");
		pr_info("\nnonce len: %zu, entropy: %zu\n",
			nonce_len_bits, entropy_len_bits);
		return CTR_DRBG_INVALID_ARG + 1;
	}

	if (reseed_interval > (1ULL << 48))
		return CTR_DRBG_INVALID_ARG + 2;

	rc = ctr_aes_init(ctx);
	if (rc)
		return CTR_DRBG_GENERAL_ERROR;

	memset(ctx->seed.as_bytes, 0, sizeof(ctx->seed.as_bytes));
	memcpy(df_input, (uint8_t *)entropy, entropy_len_bits / 8);
	memcpy(df_input + (entropy_len_bits / 8), nonce, nonce_len_bits / 8);

	update_rv = block_cipher_df(ctx, df_input, 24, seed_material, 32);
	memset(df_input, 0, 32);

	if (CTR_DRBG_SUCCESS != update_rv) {
		pr_debug("block_cipher_df failed, returns %d", update_rv);
		memset(seed_material, 0, 32);
		return CTR_DRBG_GENERAL_ERROR;
	}

	rc = crypto_ablkcipher_setkey(ctx->aes_ctx.tfm,
				ctx->seed.key_V.key,
				AES128_KEY_SIZE);
	if (rc) {
		pr_debug("crypto_ablkcipher_setkey API failed: %d", rc);
		memset(seed_material, 0, 32);
		return CTR_DRBG_GENERAL_ERROR;
	}
	update_rv = update(ctx, (const uint8_t *)seed_material, 32);
	if (update_rv != CTR_DRBG_SUCCESS) {
		memset(seed_material, 0, 32);
		return update_rv;
	}

	ctx->reseed_counter = 1;  /* think 0 but SP 800-90 says 1 */
	ctx->reseed_interval = reseed_interval;

	memset(seed_material, 0, 32);

	pr_debug(" return from ctr_drbg_instantiate\n");

	return CTR_DRBG_SUCCESS;
}