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 ); } }
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 ); } }
/* * 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; }
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 ); }
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 ); }
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 ); }
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; }