1
mirror of https://github.com/jedisct1/libsodium.git synced 2024-12-20 02:25:14 -07:00

Argon2: fill_block() now XORs blocks instead of overwriting them

This commit is contained in:
Frank Denis 2016-02-17 16:26:37 +01:00
parent e153debd0d
commit 4b6a909d8a
4 changed files with 25 additions and 18 deletions

View File

@ -123,6 +123,7 @@ static int allocate_memory(block_region **region, uint32_t m_cost) {
(*region)->base = base; (*region)->base = base;
(*region)->memory = memory; (*region)->memory = memory;
(*region)->size = base ? memory_size : 0; (*region)->size = base ? memory_size : 0;
memset(memory, 0, memory_size);
return ARGON2_OK; return ARGON2_OK;
} }

View File

@ -21,7 +21,7 @@
enum argon2_ctx_constants { enum argon2_ctx_constants {
/* Version of the algorithm */ /* Version of the algorithm */
ARGON2_VERSION_NUMBER = 0x10, ARGON2_VERSION_NUMBER = 0x13,
/* Memory block size in bytes */ /* Memory block size in bytes */
ARGON2_BLOCK_SIZE = 1024, ARGON2_BLOCK_SIZE = 1024,

View File

@ -27,15 +27,16 @@
* @param next_block Pointer to the block to be constructed * @param next_block Pointer to the block to be constructed
* @pre all block pointers must be valid * @pre all block pointers must be valid
*/ */
static void fill_block(const block *prev_block, const block *ref_block, static void fill_block_with_xor(const block *prev_block, const block *ref_block,
block *next_block) { block *next_block) {
block blockR, block_tmp; block blockR, block_tmp;
unsigned i; unsigned i;
copy_block(&blockR, ref_block); copy_block(&blockR, ref_block);
xor_block(&blockR, prev_block); xor_block(&blockR, prev_block);
copy_block(&block_tmp, &blockR); 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 /* Apply Blake2 on columns of 64-bit words: (0,1,...,15) , then
(16,17,..31)... finally (112,113,...127) */ (16,17,..31)... finally (112,113,...127) */
for (i = 0; i < 8; ++i) { 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, static void generate_addresses(const argon2_instance_t *instance,
const argon2_position_t *position, const argon2_position_t *position,
uint64_t *pseudo_rands) { uint64_t *pseudo_rands) {
block zero_block, input_block, address_block; block zero_block, input_block, address_block, tmp_block;
uint32_t i; uint32_t i;
init_block_value(&zero_block, 0); init_block_value(&zero_block, 0);
init_block_value(&input_block, 0); init_block_value(&input_block, 0);
init_block_value(&address_block, 0);
if (instance != NULL && position != NULL) { if (instance != NULL && position != NULL) {
input_block.v[0] = position->pass; 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) { for (i = 0; i < instance->segment_length; ++i) {
if (i % ARGON2_ADDRESSES_IN_BLOCK == 0) { if (i % ARGON2_ADDRESSES_IN_BLOCK == 0) {
input_block.v[6]++; input_block.v[6]++;
fill_block(&zero_block, &input_block, &address_block); init_block_value(&tmp_block, 0);
fill_block(&zero_block, &address_block, &address_block); 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]; 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 = ref_block =
instance->region->memory + instance->lane_length * ref_lane + ref_index; instance->region->memory + instance->lane_length * ref_lane + ref_index;
curr_block = instance->region->memory + curr_offset; 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); free(pseudo_rands);

View File

@ -32,13 +32,13 @@
#include "argon2-impl.h" #include "argon2-impl.h"
#include "blamka-round-ssse3.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]; __m128i block_XY[ARGON2_OWORDS_IN_BLOCK];
uint32_t i; uint32_t i;
for (i = 0; i < ARGON2_OWORDS_IN_BLOCK; i++) { for (i = 0; i < ARGON2_OWORDS_IN_BLOCK; i++) {
block_XY[i] = state[i] = _mm_xor_si128( state[i] = _mm_xor_si128(state[i], _mm_loadu_si128((__m128i const *)(&ref_block[16 * i])));
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) { 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, static void generate_addresses(const argon2_instance_t *instance,
const argon2_position_t *position, const argon2_position_t *position,
uint64_t *pseudo_rands) { uint64_t *pseudo_rands) {
block address_block, input_block; block address_block, input_block, tmp_block;
uint32_t i; uint32_t i;
init_block_value(&address_block, 0); 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) { for (i = 0; i < instance->segment_length; ++i) {
if (i % ARGON2_ADDRESSES_IN_BLOCK == 0) { if (i % ARGON2_ADDRESSES_IN_BLOCK == 0) {
/* Temporary zero-initialized blocks */
__m128i zero_block[ARGON2_OWORDS_IN_BLOCK]; __m128i zero_block[ARGON2_OWORDS_IN_BLOCK];
__m128i zero2_block[ARGON2_OWORDS_IN_BLOCK]; __m128i zero2_block[ARGON2_OWORDS_IN_BLOCK];
memset(zero_block, 0, sizeof(zero_block)); memset(zero_block, 0, sizeof(zero_block));
memset(zero2_block, 0, sizeof(zero2_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]++; input_block.v[6]++;
fill_block(zero_block, (uint8_t *)&input_block.v, /* First iteration of G */
(uint8_t *)&address_block.v); fill_block_with_xor(zero_block, (uint8_t *)&input_block.v, (uint8_t *)&tmp_block.v);
fill_block(zero2_block, (uint8_t *)&address_block.v, /* Second iteration of G */
(uint8_t *)&address_block.v); 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]; 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 = ref_block =
instance->region->memory + instance->lane_length * ref_lane + ref_index; instance->region->memory + instance->lane_length * ref_lane + ref_index;
curr_block = instance->region->memory + curr_offset; 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); free(pseudo_rands);