Skip to content

Commit

Permalink
Allow to bypass memory wipe in argon2d implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
mar-v-in authored and styppo committed May 5, 2018
1 parent 8e85685 commit fc2e45d
Show file tree
Hide file tree
Showing 9 changed files with 59 additions and 8 deletions.
1 change: 1 addition & 0 deletions clients/browser/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -452,6 +452,7 @@
<strong>Pool Server</strong>
<select pool-server-selector name="pool-server">
<option value="pool.nimiq-network.com:8080" selected>pool.nimiq-network.com:8080 (bounty)</option>
<option value="pool.nimiq-testnet.com:8444">pool.nimiq-testnet.com:8444 (test)</option>
</select>
</label>
</div>
Expand Down
2 changes: 1 addition & 1 deletion dist/worker-js.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/worker-wasm.js

Large diffs are not rendered by default.

Binary file modified dist/worker-wasm.wasm
Binary file not shown.
2 changes: 1 addition & 1 deletion src/native/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ DISTDIR := ../../dist
EMCC_BASE_FLAGS := -s NO_FILESYSTEM=1 -s ASSERTIONS=0 -s USE_CLOSURE_COMPILER=1 -s EXPORTED_RUNTIME_METHODS=[]
EMCC_WASM_FLAGS := -s WASM=1 -s DEMANGLE_SUPPORT=0 -s WARN_UNALIGNED=1
EMCC_LIB_FLAGS := -s NO_EXIT_RUNTIME=1 -s MODULARIZE=1 \
-s 'EXPORTED_FUNCTIONS=["_nimiq_blake2","_nimiq_argon2","_nimiq_argon2_verify","_nimiq_argon2_target","_nimiq_kdf","_nimiq_sha256","_ed25519_sign","_ed25519_verify","_get_static_memory_start","_get_static_memory_size","_ed25519_public_key_derive","_ed25519_create_commitment","_ed25519_add_scalars","_ed25519_aggregate_commitments","_ed25519_hash_public_keys","_ed25519_delinearize_public_key","_ed25519_aggregate_delinearized_public_keys","_ed25519_derive_delinearized_private_key","_ed25519_delinearized_partial_sign"]'
-s 'EXPORTED_FUNCTIONS=["_nimiq_blake2","_nimiq_argon2","_nimiq_argon2_no_wipe","_nimiq_argon2_verify","_nimiq_argon2_target","_nimiq_kdf","_nimiq_sha256","_ed25519_sign","_ed25519_verify","_get_static_memory_start","_get_static_memory_size","_ed25519_public_key_derive","_ed25519_create_commitment","_ed25519_add_scalars","_ed25519_aggregate_commitments","_ed25519_hash_public_keys","_ed25519_delinearize_public_key","_ed25519_aggregate_delinearized_public_keys","_ed25519_derive_delinearized_private_key","_ed25519_delinearized_partial_sign"]'
EMCC_OPT_FLAGS := -msse2

BASE_FILES := nimiq_native.c \
Expand Down
31 changes: 28 additions & 3 deletions src/native/argon2.c
Original file line number Diff line number Diff line change
Expand Up @@ -97,12 +97,12 @@ int argon2_ctx(argon2_context *context, argon2_type type) {
return ARGON2_OK;
}

int argon2_hash(const uint32_t t_cost, const uint32_t m_cost,
int _argon2_hash(const uint32_t t_cost, const uint32_t m_cost,
const uint32_t parallelism, const void *pwd,
const size_t pwdlen, const void *salt, const size_t saltlen,
void *hash, const size_t hashlen, char *encoded,
const size_t encodedlen, argon2_type type,
const uint32_t version){
const uint32_t version, const uint32_t flags){

argon2_context context;
int result;
Expand Down Expand Up @@ -145,13 +145,15 @@ int argon2_hash(const uint32_t t_cost, const uint32_t m_cost,
context.threads = parallelism;
context.allocate_cbk = NULL;
context.free_cbk = NULL;
context.flags = ARGON2_DEFAULT_FLAGS;
context.flags = flags;
context.version = version;

result = argon2_ctx(&context, type);

if (result != ARGON2_OK) {
if (!(context.flags & ARGON2_FLAG_NO_WIPE)) {
clear_internal_memory(out, hashlen);
}
free(out);
return result;
}
Expand All @@ -164,18 +166,31 @@ int argon2_hash(const uint32_t t_cost, const uint32_t m_cost,
/* if encoding requested, write it */
if (encoded && encodedlen) {
if (encode_string(encoded, encodedlen, &context, type) != ARGON2_OK) {
if (!(context.flags & ARGON2_FLAG_NO_WIPE)) {
clear_internal_memory(out, hashlen); /* wipe buffers if error */
clear_internal_memory(encoded, encodedlen);
}
free(out);
return ARGON2_ENCODING_FAIL;
}
}
if (!(context.flags & ARGON2_FLAG_NO_WIPE)) {
clear_internal_memory(out, hashlen);
}
free(out);

return ARGON2_OK;
}

int argon2_hash(const uint32_t t_cost, const uint32_t m_cost,
const uint32_t parallelism, const void *pwd,
const size_t pwdlen, const void *salt, const size_t saltlen,
void *hash, const size_t hashlen, char *encoded,
const size_t encodedlen, argon2_type type,
const uint32_t version){
return _argon2_hash(t_cost, m_cost, parallelism, pwd, pwdlen, salt, saltlen, hash, hashlen, encoded, encodedlen, type, version, ARGON2_DEFAULT_FLAGS);
}

int argon2i_hash_encoded(const uint32_t t_cost, const uint32_t m_cost,
const uint32_t parallelism, const void *pwd,
const size_t pwdlen, const void *salt,
Expand Down Expand Up @@ -216,6 +231,16 @@ int argon2d_hash_raw(const uint32_t t_cost, const uint32_t m_cost,
hash, hashlen, NULL, 0, Argon2_d, ARGON2_VERSION_NUMBER);
}

int argon2d_hash_raw_flags(const uint32_t t_cost, const uint32_t m_cost,
const uint32_t parallelism, const void *pwd,
const size_t pwdlen, const void *salt,
const size_t saltlen, void *hash, const size_t hashlen,
const uint32_t flags) {

return _argon2_hash(t_cost, m_cost, parallelism, pwd, pwdlen, salt, saltlen,
hash, hashlen, NULL, 0, Argon2_d, ARGON2_VERSION_NUMBER, flags);
}

int argon2id_hash_encoded(const uint32_t t_cost, const uint32_t m_cost,
const uint32_t parallelism, const void *pwd,
const size_t pwdlen, const void *salt,
Expand Down
7 changes: 7 additions & 0 deletions src/native/argon2.h
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ extern "C" {
#define ARGON2_DEFAULT_FLAGS UINT32_C(0)
#define ARGON2_FLAG_CLEAR_PASSWORD (UINT32_C(1) << 0)
#define ARGON2_FLAG_CLEAR_SECRET (UINT32_C(1) << 1)
#define ARGON2_FLAG_NO_WIPE (UINT32_C(1) << 2)

/* Global flag to determine if we are wiping internal memory buffers. This flag
* is defined in core.c and deafults to 1 (wipe internal memory). */
Expand Down Expand Up @@ -303,6 +304,12 @@ ARGON2_PUBLIC int argon2d_hash_raw(const uint32_t t_cost, const uint32_t m_cost,
const size_t saltlen, void *hash,
const size_t hashlen);

ARGON2_PUBLIC int argon2d_hash_raw_flags(const uint32_t t_cost, const uint32_t m_cost,
const uint32_t parallelism, const void *pwd,
const size_t pwdlen, const void *salt,
const size_t saltlen, void *hash,
const size_t hashlen, const uint32_t flags);

ARGON2_PUBLIC int argon2id_hash_encoded(const uint32_t t_cost,
const uint32_t m_cost,
const uint32_t parallelism,
Expand Down
10 changes: 10 additions & 0 deletions src/native/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,9 @@ int allocate_memory(const argon2_context *context, uint8_t **memory,
void free_memory(const argon2_context *context, uint8_t *memory,
size_t num, size_t size) {
size_t memory_size = num*size;
if (!(context->flags & ARGON2_FLAG_NO_WIPE)) {
clear_internal_memory(memory, memory_size);
}
if (context->free_cbk) {
(context->free_cbk)(memory, memory_size);
} else {
Expand Down Expand Up @@ -164,8 +166,10 @@ void finalize(const argon2_context *context, argon2_instance_t *instance) {
blake2b_long(context->out, context->outlen, blockhash_bytes,
ARGON2_BLOCK_SIZE);
/* clear blockhash and blockhash_bytes */
if (!(context->flags & ARGON2_FLAG_NO_WIPE)) {
clear_internal_memory(blockhash.v, ARGON2_BLOCK_SIZE);
clear_internal_memory(blockhash_bytes, ARGON2_BLOCK_SIZE);
}
}

#ifdef GENKAT
Expand Down Expand Up @@ -520,7 +524,9 @@ void fill_first_blocks(uint8_t *blockhash, const argon2_instance_t *instance) {
load_block(&instance->memory[l * instance->lane_length + 1],
blockhash_bytes);
}
if (!(instance->context_ptr->flags & ARGON2_FLAG_NO_WIPE)) {
clear_internal_memory(blockhash_bytes, ARGON2_BLOCK_SIZE);
}
}

void initial_hash(uint8_t *blockhash, argon2_context *context,
Expand Down Expand Up @@ -618,9 +624,11 @@ int initialize(argon2_instance_t *instance, argon2_context *context) {
/* Hashing all inputs */
initial_hash(blockhash, context, instance->type);
/* Zeroing 8 extra bytes */
if (!(context->flags & ARGON2_FLAG_NO_WIPE)) {
clear_internal_memory(blockhash + ARGON2_PREHASH_DIGEST_LENGTH,
ARGON2_PREHASH_SEED_LENGTH -
ARGON2_PREHASH_DIGEST_LENGTH);
}

#ifdef GENKAT
initial_kat(blockhash, context, instance->type);
Expand All @@ -630,7 +638,9 @@ int initialize(argon2_instance_t *instance, argon2_context *context) {
*/
fill_first_blocks(blockhash, instance);
/* Clearing the hash */
if (!(context->flags & ARGON2_FLAG_NO_WIPE)) {
clear_internal_memory(blockhash, ARGON2_PREHASH_SEED_LENGTH);
}

return ARGON2_OK;
}
12 changes: 10 additions & 2 deletions src/native/nimiq_native.c
Original file line number Diff line number Diff line change
Expand Up @@ -85,8 +85,16 @@ void nimiq_sha256(void *out, const void *in, const size_t inlen) {
sha256_final(&ctx, out);
}

inline int nimiq_argon2_flags(void *out, const void *in, const size_t inlen, const uint32_t m_cost, const uint32_t flags) {
return argon2d_hash_raw_flags(1, m_cost == 0 ? NIMIQ_DEFAULT_ARGON2_COST : m_cost, 1, in, inlen, NIMIQ_ARGON2_SALT, NIMIQ_ARGON2_SALT_LEN, out, 32, flags);
}

int nimiq_argon2(void *out, const void *in, const size_t inlen, const uint32_t m_cost) {
return argon2d_hash_raw(1, m_cost == 0 ? NIMIQ_DEFAULT_ARGON2_COST : m_cost, 1, in, inlen, NIMIQ_ARGON2_SALT, NIMIQ_ARGON2_SALT_LEN, out, 32);
return nimiq_argon2_flags(out, in, inlen, m_cost, ARGON2_DEFAULT_FLAGS);
}

int nimiq_argon2_no_wipe(void *out, const void *in, const size_t inlen, const uint32_t m_cost) {
return nimiq_argon2_flags(out, in, inlen, m_cost, ARGON2_DEFAULT_FLAGS | ARGON2_FLAG_NO_WIPE);
}

int nimiq_kdf(void *out, const void *in, const size_t inlen, const void* seed, const size_t seedlen, const uint32_t m_cost, const uint32_t iter) {
Expand All @@ -105,7 +113,7 @@ uint32_t nimiq_argon2_target(void *out, void *in, const size_t inlen, const uint
uint256 target = uint256_new(), hash = uint256_new();
uint256_set_compact(target, compact);
for(noncer[0] = htonl(min_nonce); ntohl(noncer[0]) < max_nonce; noncer[0] = htonl(ntohl(noncer[0])+1)) {
nimiq_argon2(out, in, inlen, m_cost);
nimiq_argon2_no_wipe(out, in, inlen, m_cost);
uint256_set_bytes(hash, out);
if (uint256_compare(target, hash) > 0) {
break;
Expand Down

0 comments on commit fc2e45d

Please sign in to comment.