mirror of
https://github.com/jedisct1/libsodium.git
synced 2026-08-25 08:37:13 +09:00
Argon2: deallocate memory if fill_memory_blocks() ever fails
Also perform a single allocation to store random numbers.
This commit is contained in:
@@ -170,7 +170,7 @@ static void free_memory(block_region *memory);
|
||||
static void
|
||||
free_memory(block_region *region)
|
||||
{
|
||||
if (region->base) {
|
||||
if (region && region->base) {
|
||||
#if defined(MAP_ANON) && defined(HAVE_MMAP)
|
||||
if (munmap(region->base, region->size)) {
|
||||
return; /* LCOV_EXCL_LINE */
|
||||
@@ -182,6 +182,19 @@ free_memory(block_region *region)
|
||||
free(region);
|
||||
}
|
||||
|
||||
void
|
||||
free_instance(argon2_instance_t *instance, int flags)
|
||||
{
|
||||
/* Clear memory */
|
||||
clear_memory(instance, flags & ARGON2_FLAG_CLEAR_PASSWORD);
|
||||
|
||||
/* Deallocate the memory */
|
||||
free(instance->pseudo_rands);
|
||||
instance->pseudo_rands = NULL;
|
||||
free_memory(instance->region);
|
||||
instance->region = NULL;
|
||||
}
|
||||
|
||||
void
|
||||
finalize(const argon2_context *context, argon2_instance_t *instance)
|
||||
{
|
||||
@@ -212,11 +225,7 @@ finalize(const argon2_context *context, argon2_instance_t *instance)
|
||||
ARGON2_BLOCK_SIZE); /* clear blockhash_bytes */
|
||||
}
|
||||
|
||||
/* Clear memory */
|
||||
clear_memory(instance, context->flags & ARGON2_FLAG_CLEAR_PASSWORD);
|
||||
|
||||
/* Deallocate the memory */
|
||||
free_memory(instance->region);
|
||||
free_instance(instance, context->flags);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -544,7 +553,7 @@ initial_hash(uint8_t *blockhash, argon2_context *context, argon2_type type)
|
||||
STORE32_LE(value, context->adlen);
|
||||
crypto_generichash_blake2b_update(&BlakeHash, value, sizeof(value));
|
||||
|
||||
/* LCOV_EXCL_START */
|
||||
/* LCOV_EXCL_START */
|
||||
if (context->ad != NULL) {
|
||||
crypto_generichash_blake2b_update(
|
||||
&BlakeHash, (const uint8_t *) context->ad, context->adlen);
|
||||
@@ -561,13 +570,20 @@ initialize(argon2_instance_t *instance, argon2_context *context)
|
||||
uint8_t blockhash[ARGON2_PREHASH_SEED_LENGTH];
|
||||
int result = ARGON2_OK;
|
||||
|
||||
if (instance == NULL || context == NULL)
|
||||
if (instance == NULL || context == NULL) {
|
||||
return ARGON2_INCORRECT_PARAMETER;
|
||||
}
|
||||
|
||||
/* 1. Memory allocation */
|
||||
|
||||
if ((instance->pseudo_rands =
|
||||
malloc(sizeof(uint64_t) * instance->segment_length)) == NULL) {
|
||||
return ARGON2_MEMORY_ALLOCATION_ERROR;
|
||||
}
|
||||
|
||||
result = allocate_memory(&(instance->region), instance->memory_blocks);
|
||||
if (ARGON2_OK != result) {
|
||||
free_instance(instance, context->flags);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
@@ -76,6 +76,7 @@ void xor_block(block *dst, const block *src);
|
||||
*/
|
||||
typedef struct Argon2_instance_t {
|
||||
block_region *region; /* Memory region pointer */
|
||||
uint64_t *pseudo_rands;
|
||||
uint32_t passes; /* Number of passes */
|
||||
uint32_t memory_blocks; /* Number of blocks in memory */
|
||||
uint32_t segment_length;
|
||||
@@ -162,6 +163,11 @@ void fill_first_blocks(uint8_t *blockhash, const argon2_instance_t *instance);
|
||||
*/
|
||||
int initialize(argon2_instance_t *instance, argon2_context *context);
|
||||
|
||||
/*
|
||||
* Deallocates memory. Used on error path.
|
||||
*/
|
||||
void free_instance(argon2_instance_t *instance, int flags);
|
||||
|
||||
/*
|
||||
* XORing the last block of each lane, hashing it, making the tag. Deallocates
|
||||
* the memory.
|
||||
|
||||
@@ -163,11 +163,7 @@ fill_segment_avx2(const argon2_instance_t *instance,
|
||||
data_independent_addressing = 0;
|
||||
}
|
||||
|
||||
pseudo_rands =
|
||||
(uint64_t *) malloc(sizeof(uint64_t) * instance->segment_length);
|
||||
if (pseudo_rands == NULL) {
|
||||
return ARGON2_MEMORY_ALLOCATION_ERROR;
|
||||
}
|
||||
pseudo_rands = instance->pseudo_rands;
|
||||
|
||||
if (data_independent_addressing) {
|
||||
generate_addresses(instance, &position, pseudo_rands);
|
||||
@@ -240,8 +236,6 @@ fill_segment_avx2(const argon2_instance_t *instance,
|
||||
}
|
||||
}
|
||||
|
||||
free(pseudo_rands);
|
||||
|
||||
return ARGON2_OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -161,12 +161,7 @@ fill_segment_ref(const argon2_instance_t *instance, argon2_position_t position)
|
||||
data_independent_addressing = 0;
|
||||
}
|
||||
|
||||
pseudo_rands =
|
||||
(uint64_t *) malloc(sizeof(uint64_t) * (instance->segment_length));
|
||||
|
||||
if (pseudo_rands == NULL) {
|
||||
return ARGON2_MEMORY_ALLOCATION_ERROR;
|
||||
}
|
||||
pseudo_rands = instance->pseudo_rands;
|
||||
|
||||
if (data_independent_addressing) {
|
||||
generate_addresses(instance, &position, pseudo_rands);
|
||||
@@ -236,7 +231,5 @@ fill_segment_ref(const argon2_instance_t *instance, argon2_position_t position)
|
||||
}
|
||||
}
|
||||
|
||||
free(pseudo_rands);
|
||||
|
||||
return ARGON2_OK;
|
||||
}
|
||||
|
||||
@@ -162,11 +162,7 @@ fill_segment_ssse3(const argon2_instance_t *instance,
|
||||
data_independent_addressing = 0;
|
||||
}
|
||||
|
||||
pseudo_rands =
|
||||
(uint64_t *) malloc(sizeof(uint64_t) * instance->segment_length);
|
||||
if (pseudo_rands == NULL) {
|
||||
return ARGON2_MEMORY_ALLOCATION_ERROR;
|
||||
}
|
||||
pseudo_rands = instance->pseudo_rands;
|
||||
|
||||
if (data_independent_addressing) {
|
||||
generate_addresses(instance, &position, pseudo_rands);
|
||||
@@ -239,8 +235,6 @@ fill_segment_ssse3(const argon2_instance_t *instance,
|
||||
}
|
||||
}
|
||||
|
||||
free(pseudo_rands);
|
||||
|
||||
return ARGON2_OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -73,6 +73,7 @@ argon2_ctx(argon2_context *context, argon2_type type)
|
||||
result = fill_memory_blocks(&instance);
|
||||
|
||||
if (ARGON2_OK != result) {
|
||||
free_instance(&instance, context->flags);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user