From 4b6a909d8acd6aa477faa79c7b8cc3c102f57908 Mon Sep 17 00:00:00 2001 From: Frank Denis Date: Wed, 17 Feb 2016 16:26:37 +0100 Subject: [PATCH] Argon2: fill_block() now XORs blocks instead of overwriting them --- .../crypto_pwhash/argon2/argon2-core.c | 1 + .../crypto_pwhash/argon2/argon2-core.h | 2 +- .../argon2/argon2-fill-block-ref.c | 18 ++++++++------- .../argon2/argon2-fill-block-ssse3.c | 22 +++++++++++-------- 4 files changed, 25 insertions(+), 18 deletions(-) diff --git a/src/libsodium/crypto_pwhash/argon2/argon2-core.c b/src/libsodium/crypto_pwhash/argon2/argon2-core.c index 0c53ba80..d819df8c 100644 --- a/src/libsodium/crypto_pwhash/argon2/argon2-core.c +++ b/src/libsodium/crypto_pwhash/argon2/argon2-core.c @@ -123,6 +123,7 @@ static int allocate_memory(block_region **region, uint32_t m_cost) { (*region)->base = base; (*region)->memory = memory; (*region)->size = base ? memory_size : 0; + memset(memory, 0, memory_size); return ARGON2_OK; } diff --git a/src/libsodium/crypto_pwhash/argon2/argon2-core.h b/src/libsodium/crypto_pwhash/argon2/argon2-core.h index 733e532e..941eea63 100644 --- a/src/libsodium/crypto_pwhash/argon2/argon2-core.h +++ b/src/libsodium/crypto_pwhash/argon2/argon2-core.h @@ -21,7 +21,7 @@ enum argon2_ctx_constants { /* Version of the algorithm */ - ARGON2_VERSION_NUMBER = 0x10, + ARGON2_VERSION_NUMBER = 0x13, /* Memory block size in bytes */ ARGON2_BLOCK_SIZE = 1024, diff --git a/src/libsodium/crypto_pwhash/argon2/argon2-fill-block-ref.c b/src/libsodium/crypto_pwhash/argon2/argon2-fill-block-ref.c index 5101617f..973791b4 100644 --- a/src/libsodium/crypto_pwhash/argon2/argon2-fill-block-ref.c +++ b/src/libsodium/crypto_pwhash/argon2/argon2-fill-block-ref.c @@ -27,15 +27,16 @@ * @param next_block Pointer to the block to be constructed * @pre all block pointers must be valid */ -static void fill_block(const block *prev_block, const block *ref_block, - block *next_block) { +static void fill_block_with_xor(const block *prev_block, const block *ref_block, + block *next_block) { block blockR, block_tmp; unsigned i; copy_block(&blockR, ref_block); xor_block(&blockR, prev_block); copy_block(&block_tmp, &blockR); - + xor_block(&block_tmp, next_block); /* Saving the next block contents for XOR over */ + /* Now blockR = ref_block + prev_block and bloc_tmp = ref_block + prev_block + next_block */ /* Apply Blake2 on columns of 64-bit words: (0,1,...,15) , then (16,17,..31)... finally (112,113,...127) */ for (i = 0; i < 8; ++i) { @@ -75,12 +76,11 @@ static void fill_block(const block *prev_block, const block *ref_block, static void generate_addresses(const argon2_instance_t *instance, const argon2_position_t *position, uint64_t *pseudo_rands) { - block zero_block, input_block, address_block; + block zero_block, input_block, address_block, tmp_block; uint32_t i; init_block_value(&zero_block, 0); init_block_value(&input_block, 0); - init_block_value(&address_block, 0); if (instance != NULL && position != NULL) { input_block.v[0] = position->pass; @@ -93,8 +93,10 @@ static void generate_addresses(const argon2_instance_t *instance, for (i = 0; i < instance->segment_length; ++i) { if (i % ARGON2_ADDRESSES_IN_BLOCK == 0) { input_block.v[6]++; - fill_block(&zero_block, &input_block, &address_block); - fill_block(&zero_block, &address_block, &address_block); + init_block_value(&tmp_block, 0); + init_block_value(&address_block, 0); + fill_block_with_xor(&zero_block, &input_block, &tmp_block); + fill_block_with_xor(&zero_block, &tmp_block, &address_block); } pseudo_rands[i] = address_block.v[i % ARGON2_ADDRESSES_IN_BLOCK]; @@ -182,7 +184,7 @@ int fill_segment_ref(const argon2_instance_t *instance, ref_block = instance->region->memory + instance->lane_length * ref_lane + ref_index; curr_block = instance->region->memory + curr_offset; - fill_block(instance->region->memory + prev_offset, ref_block, curr_block); + fill_block_with_xor(instance->region->memory + prev_offset, ref_block, curr_block); } free(pseudo_rands); diff --git a/src/libsodium/crypto_pwhash/argon2/argon2-fill-block-ssse3.c b/src/libsodium/crypto_pwhash/argon2/argon2-fill-block-ssse3.c index 11aa6634..7d010beb 100644 --- a/src/libsodium/crypto_pwhash/argon2/argon2-fill-block-ssse3.c +++ b/src/libsodium/crypto_pwhash/argon2/argon2-fill-block-ssse3.c @@ -32,13 +32,13 @@ #include "argon2-impl.h" #include "blamka-round-ssse3.h" -static void fill_block(__m128i *state, const uint8_t *ref_block, uint8_t *next_block) { +static void fill_block_with_xor(__m128i *state, const uint8_t *ref_block, uint8_t *next_block) { __m128i block_XY[ARGON2_OWORDS_IN_BLOCK]; uint32_t i; for (i = 0; i < ARGON2_OWORDS_IN_BLOCK; i++) { - block_XY[i] = state[i] = _mm_xor_si128( - state[i], _mm_loadu_si128((__m128i const *)(&ref_block[16 * i]))); + state[i] = _mm_xor_si128(state[i], _mm_loadu_si128((__m128i const *)(&ref_block[16 * i]))); + block_XY[i] = _mm_xor_si128(state[i], _mm_loadu_si128((__m128i const *)(&next_block[16 * i]))); } for (i = 0; i < 8; ++i) { @@ -62,7 +62,7 @@ static void fill_block(__m128i *state, const uint8_t *ref_block, uint8_t *next_b static void generate_addresses(const argon2_instance_t *instance, const argon2_position_t *position, uint64_t *pseudo_rands) { - block address_block, input_block; + block address_block, input_block, tmp_block; uint32_t i; init_block_value(&address_block, 0); @@ -78,15 +78,19 @@ static void generate_addresses(const argon2_instance_t *instance, for (i = 0; i < instance->segment_length; ++i) { if (i % ARGON2_ADDRESSES_IN_BLOCK == 0) { + /* Temporary zero-initialized blocks */ __m128i zero_block[ARGON2_OWORDS_IN_BLOCK]; __m128i zero2_block[ARGON2_OWORDS_IN_BLOCK]; memset(zero_block, 0, sizeof(zero_block)); memset(zero2_block, 0, sizeof(zero2_block)); + init_block_value(&address_block, 0); + init_block_value(&tmp_block, 0); + /* Increasing index counter */ input_block.v[6]++; - fill_block(zero_block, (uint8_t *)&input_block.v, - (uint8_t *)&address_block.v); - fill_block(zero2_block, (uint8_t *)&address_block.v, - (uint8_t *)&address_block.v); + /* First iteration of G */ + fill_block_with_xor(zero_block, (uint8_t *)&input_block.v, (uint8_t *)&tmp_block.v); + /* Second iteration of G */ + fill_block_with_xor(zero2_block, (uint8_t *)&tmp_block.v, (uint8_t *)&address_block.v); } pseudo_rands[i] = address_block.v[i % ARGON2_ADDRESSES_IN_BLOCK]; @@ -176,7 +180,7 @@ int fill_segment_ssse3(const argon2_instance_t *instance, ref_block = instance->region->memory + instance->lane_length * ref_lane + ref_index; curr_block = instance->region->memory + curr_offset; - fill_block(state, (uint8_t *)ref_block->v, (uint8_t *)curr_block->v); + fill_block_with_xor(state, (uint8_t *)ref_block->v, (uint8_t *)curr_block->v); } free(pseudo_rands);