diff options
author | Nikos Mavrogiannopoulos <nmav@redhat.com> | 2015-06-03 14:36:35 +0200 |
---|---|---|
committer | Nikos Mavrogiannopoulos <nmav@redhat.com> | 2015-06-04 13:41:55 +0200 |
commit | 56ebdc59018951a75c325938ef39fdc5169f8abd (patch) | |
tree | 8d611047907f5cf6ffe8190929924b7cf7eabc3f | |
parent | 16bdf9c11b823069768d00a7135bafe7ab3117af (diff) | |
download | gnutls-56ebdc59018951a75c325938ef39fdc5169f8abd.tar.gz |
fips140: enforce the max_number_of_bits_per_request
-rw-r--r-- | lib/nettle/int/drbg-aes.c | 33 | ||||
-rw-r--r-- | lib/nettle/int/drbg-aes.h | 10 |
2 files changed, 36 insertions, 7 deletions
diff --git a/lib/nettle/int/drbg-aes.c b/lib/nettle/int/drbg-aes.c index 5ff2484e43..6835385356 100644 --- a/lib/nettle/int/drbg-aes.c +++ b/lib/nettle/int/drbg-aes.c @@ -97,6 +97,26 @@ drbg_aes_reseed(struct drbg_aes_ctx *ctx, return 1; } +int drbg_aes_random(struct drbg_aes_ctx *ctx, unsigned length, uint8_t * dst) +{ + unsigned p_len; + int left = length; + uint8_t *p = dst; + int ret; + + while(left > 0) { + p_len = MIN(MAX_DRBG_AES_GENERATE_SIZE, left); + ret = drbg_aes_generate(ctx, p_len, p, 0, 0); + if (ret == 0) + return ret; + + p += p_len; + left -= p_len; + } + + return 1; +} + /* we don't use additional input */ int drbg_aes_generate(struct drbg_aes_ctx *ctx, unsigned length, uint8_t * dst, unsigned add_size, const uint8_t *add) @@ -106,11 +126,14 @@ int drbg_aes_generate(struct drbg_aes_ctx *ctx, unsigned length, uint8_t * dst, unsigned left; if (ctx->seeded == 0) - return 0; + return gnutls_assert_val(0); + + if (length > MAX_DRBG_AES_GENERATE_SIZE) + return gnutls_assert_val(0); if (add_size > 0) { if (add_size > DRBG_AES_SEED_SIZE) - return 0; + return gnutls_assert_val(0); memcpy(seed, add, add_size); if (add_size != DRBG_AES_SEED_SIZE) memset(&seed[add_size], 0, DRBG_AES_SEED_SIZE - add_size); @@ -140,7 +163,7 @@ int drbg_aes_generate(struct drbg_aes_ctx *ctx, unsigned length, uint8_t * dst, /* if detected loop */ if (memcmp(dst, ctx->prev_block, AES_BLOCK_SIZE) == 0) { _gnutls_switch_lib_state(LIB_STATE_ERROR); - return 0; + return gnutls_assert_val(0); } memcpy(ctx->prev_block, dst, AES_BLOCK_SIZE); @@ -154,7 +177,7 @@ int drbg_aes_generate(struct drbg_aes_ctx *ctx, unsigned length, uint8_t * dst, /* if detected loop */ if (memcmp(tmp, ctx->prev_block, AES_BLOCK_SIZE) == 0) { _gnutls_switch_lib_state(LIB_STATE_ERROR); - return 0; + return gnutls_assert_val(0); } memcpy(ctx->prev_block, tmp, AES_BLOCK_SIZE); @@ -162,7 +185,7 @@ int drbg_aes_generate(struct drbg_aes_ctx *ctx, unsigned length, uint8_t * dst, } if (ctx->reseed_counter > DRBG_AES_RESEED_TIME) - return 0; + return gnutls_assert_val(0); ctx->reseed_counter++; drbg_aes_update(ctx, seed); diff --git a/lib/nettle/int/drbg-aes.h b/lib/nettle/int/drbg-aes.h index eb89be6386..72608defe8 100644 --- a/lib/nettle/int/drbg-aes.h +++ b/lib/nettle/int/drbg-aes.h @@ -55,10 +55,13 @@ struct drbg_aes_ctx { unsigned reseed_counter; }; +/* max_number_of_bits_per_request */ +#define MAX_DRBG_AES_GENERATE_SIZE 65536 /* 2^19 */ + /* This DRBG should be reseeded if reseed_counter exceeds * that number. Otherwise drbg_aes_random() will fail. */ -#define DRBG_AES_RESEED_TIME 65536 +#define DRBG_AES_RESEED_TIME 16777216 /* The entropy provided in these functions should be of * size DRBG_AES_SEED_SIZE. Additional data and pers. @@ -74,7 +77,10 @@ drbg_aes_reseed(struct drbg_aes_ctx *ctx, unsigned entropy_size, const uint8_t *entropy, unsigned add_size, const uint8_t* add); -#define drbg_aes_random(ctx, l, dst) drbg_aes_generate(ctx, l, dst, 0, NULL) +/* our wrapper for the low-level drbg_aes_generate */ +int +drbg_aes_random(struct drbg_aes_ctx *ctx, unsigned length, + uint8_t * dst); int drbg_aes_generate(struct drbg_aes_ctx *ctx, unsigned length, |