2
0
Fork 0
mirror of https://git.sr.ht/~sircmpwn/mkproof synced 2024-06-09 05:06:06 +02:00

more snake_case, switch to C89, flags as uint32_t

This commit is contained in:
Samuel Neves 2015-10-27 00:26:25 +00:00
parent d000ced1ac
commit e0fa49a7a2
17 changed files with 474 additions and 436 deletions

View File

@ -15,7 +15,7 @@ SRC = src/argon2.c src/core.c src/kat.c src/blake2/blake2b-ref.c src/thread.c
SRC_MAIN = src/main.c
OBJ = $(SRC:.c=.o)
CFLAGS = -std=c99 -pthread -O3 -Wall -g
CFLAGS = -std=c89 -pthread -O3 -Wall -g
CFLAGS_OPT = $(CFLAGS)
#OPT=TRUE

View File

@ -12,7 +12,6 @@
*/
#include <stdint.h>
#include <stdbool.h>
#include <string.h>
#include <stdio.h>
@ -21,7 +20,7 @@
/* Error messages */
const char *Argon2_ErrorMessage[] = {
static const char *Argon2_ErrorMessage[] = {
/*{ARGON2_OK, */ "OK",
/*},
@ -96,28 +95,25 @@ const char *Argon2_ErrorMessage[] = {
int hash_argon2i(void *out, size_t outlen, const void *in, size_t inlen,
const void *salt, size_t saltlen, unsigned int t_cost,
unsigned int m_cost) {
Argon2_Context context = {
(uint8_t *)out,
(uint32_t)outlen,
(uint8_t *)in,
(uint32_t)inlen,
(uint8_t *)salt,
(uint32_t)saltlen,
NULL, /*Pointer to the secret*/
0, /*Secret length*/
NULL, /*Pointer to the associated data*/
0, /*Associated data length*/
(uint32_t)t_cost,
(uint32_t)m_cost,
1, /*Number of lanes*/
1, /*Number of threads*/
NULL,
NULL, /*Pointers to external memory (de)allocators*/
true, /*Clear the password after use*/
false, /*Not use the secret so not clear it*/
true, /*Clear the memory after use*/
false /*Not printing the memory content to the file*/
};
argon2_context context;
context.out = (uint8_t *)out;
context.outlen = outlen;
context.pwd = (uint8_t *)in;
context.pwdlen = inlen;
context.salt = (uint8_t *)salt;
context.saltlen = saltlen;
context.secret = NULL;
context.secretlen = 0;
context.ad = NULL;
context.adlen = 0;
context.t_cost = t_cost;
context.m_cost = m_cost;
context.lanes = 1;
context.threads = 1;
context.allocate_cbk = NULL;
context.free_cbk = NULL;
context.flags = ARGON2_DEFAULT_FLAGS;
return argon2_core(&context, Argon2_i);
}
@ -125,40 +121,40 @@ int hash_argon2i(void *out, size_t outlen, const void *in, size_t inlen,
int hash_argon2d(void *out, size_t outlen, const void *in, size_t inlen,
const void *salt, size_t saltlen, unsigned int t_cost,
unsigned int m_cost) {
Argon2_Context context = {(uint8_t *)out,
(uint32_t)outlen,
(uint8_t *)in,
(uint32_t)inlen,
(uint8_t *)salt,
(uint32_t)saltlen,
NULL,
0,
NULL,
0,
(uint32_t)t_cost,
(uint32_t)m_cost,
1,
1,
NULL,
NULL,
true,
true,
true,
false};
argon2_context context;
context.out = (uint8_t *)out;
context.outlen = outlen;
context.pwd = (uint8_t *)in;
context.pwdlen = inlen;
context.salt = (uint8_t *)salt;
context.saltlen = saltlen;
context.secret = NULL;
context.secretlen = 0;
context.ad = NULL;
context.adlen = 0;
context.t_cost = t_cost;
context.m_cost = m_cost;
context.lanes = 1;
context.threads = 1;
context.allocate_cbk = NULL;
context.free_cbk = NULL;
context.flags = ARGON2_DEFAULT_FLAGS;
return argon2_core(&context, Argon2_d);
}
int argon2d(Argon2_Context *context) { return argon2_core(context, Argon2_d); }
int argon2d(argon2_context *context) { return argon2_core(context, Argon2_d); }
int argon2i(Argon2_Context *context) { return argon2_core(context, Argon2_i); }
int argon2i(argon2_context *context) { return argon2_core(context, Argon2_i); }
int verify_d(Argon2_Context *context, const char *hash) {
int verify_d(argon2_context *context, const char *hash) {
int result;
if (0 == context->outlen || NULL == hash) {
return ARGON2_OUT_PTR_MISMATCH;
}
int result = argon2_core(context, Argon2_d);
result = argon2_core(context, Argon2_d);
if (ARGON2_OK != result) {
return result;
@ -169,8 +165,7 @@ int verify_d(Argon2_Context *context, const char *hash) {
const char *error_message(int error_code) {
if (error_code < ARGON2_ERROR_CODES_LENGTH) {
return Argon2_ErrorMessage[(Argon2_ErrorCodes)error_code];
return Argon2_ErrorMessage[(argon2_error_codes)error_code];
}
return "Unknown error code.";
}

View File

@ -15,7 +15,6 @@
#include <stdint.h>
#include <stddef.h>
#include <stdbool.h>
#if defined(__cplusplus)
extern "C" {
@ -28,49 +27,53 @@ const char *ARGON2_KAT_FILENAME;
* restrictions**************************************************/
/* Minimum and maximum number of lanes (degree of parallelism) */
#define ARGON2_MIN_LANES 1
#define ARGON2_MAX_LANES 0xFFFFFF
#define ARGON2_MIN_LANES UINT32_C(1)
#define ARGON2_MAX_LANES UINT32_C(0xFFFFFF)
/* Minimum and maximum number of threads */
#define ARGON2_MIN_THREADS 1
#define ARGON2_MAX_THREADS 0xFFFFFF
#define ARGON2_MIN_THREADS UINT32_C(1)
#define ARGON2_MAX_THREADS UINT32_C(0xFFFFFF)
/* Number of synchronization points between lanes per pass */
#define __ARGON_SYNC_POINTS 4
#define ARGON2_SYNC_POINTS __ARGON_SYNC_POINTS
#define ARGON2_SYNC_POINTS UINT32_C(4)
/* Minimum and maximum digest size in bytes */
#define ARGON2_MIN_OUTLEN 4
#define ARGON2_MAX_OUTLEN 0xFFFFFFFF
#define ARGON2_MIN_OUTLEN UINT32_C(4)
#define ARGON2_MAX_OUTLEN UINT32_C(0xFFFFFFFF)
/* Minimum and maximum number of memory blocks (each of BLOCK_SIZE bytes) */
#define ARGON2_MIN_MEMORY (2 *(__ARGON_SYNC_POINTS)) // 2 blocks per slice
#define ARGON2_MAX_MEMORY 0xFFFFFFFF // 2^32-1 blocks
#define ARGON2_32BIT_LIMIT 0x200000 //2^21 blocks for 32-bit machines
#define ARGON2_MIN_MEMORY (2 * ARGON2_SYNC_POINTS) /* 2 blocks per slice */
#define ARGON2_MAX_MEMORY UINT32_C(0xFFFFFFFF) /* 2^32-1 blocks */
#define ARGON2_32BIT_LIMIT UINT32_C(0x200000) /* 2^21 blocks for 32-bit machines */
/* Minimum and maximum number of passes */
#define ARGON2_MIN_TIME 1
#define ARGON2_MAX_TIME 0xFFFFFFFF
#define ARGON2_MIN_TIME UINT32_C(1)
#define ARGON2_MAX_TIME UINT32_C(0xFFFFFFFF)
/* Minimum and maximum password length in bytes */
#define ARGON2_MIN_PWD_LENGTH 0
#define ARGON2_MAX_PWD_LENGTH 0xFFFFFFFF
#define ARGON2_MIN_PWD_LENGTH UINT32_C(0)
#define ARGON2_MAX_PWD_LENGTH UINT32_C(0xFFFFFFFF)
/* Minimum and maximum associated data length in bytes */
#define ARGON2_MIN_AD_LENGTH 0
#define ARGON2_MAX_AD_LENGTH 0xFFFFFFFF
#define ARGON2_MIN_AD_LENGTH UINT32_C(0)
#define ARGON2_MAX_AD_LENGTH UINT32_C(0xFFFFFFFF)
/* Minimum and maximum salt length in bytes */
#define ARGON2_MIN_SALT_LENGTH 8
#define ARGON2_MAX_SALT_LENGTH 0xFFFFFFFF
#define ARGON2_MIN_SALT_LENGTH UINT32_C(8)
#define ARGON2_MAX_SALT_LENGTH UINT32_C(0xFFFFFFFF)
/* Minimum and maximum key length in bytes */
#define ARGON2_MIN_SECRET 0
#define ARGON2_MAX_SECRET 0xFFFFFFFF
#define ARGON2_MIN_SECRET UINT32_C(0)
#define ARGON2_MAX_SECRET UINT32_C(0xFFFFFFFF)
#define ARGON2_CLEAR_PASSWORD (UINT32_C(1) << 0)
#define ARGON2_CLEAR_SECRET (UINT32_C(1) << 1)
#define ARGON2_CLEAR_MEMORY (UINT32_C(1) << 2)
#define ARGON2_PRINT (UINT32_C(1) << 3)
#define ARGON2_DEFAULT_FLAGS (ARGON2_CLEAR_PASSWORD | ARGON2_CLEAR_MEMORY)
/* Error codes */
typedef enum _Argon2_ErrorCodes {
typedef enum Argon2_ErrorCodes {
ARGON2_OK = 0,
ARGON2_OUTPUT_PTR_NULL = 1,
@ -99,10 +102,10 @@ typedef enum _Argon2_ErrorCodes {
ARGON2_LANES_TOO_FEW = 16,
ARGON2_LANES_TOO_MANY = 17,
ARGON2_PWD_PTR_MISMATCH = 18, // NULL ptr with non-zero length
ARGON2_SALT_PTR_MISMATCH = 19, // NULL ptr with non-zero length
ARGON2_SECRET_PTR_MISMATCH = 20, // NULL ptr with non-zero length
ARGON2_AD_PTR_MISMATCH = 21, // NULL ptr with non-zero length
ARGON2_PWD_PTR_MISMATCH = 18, /* NULL ptr with non-zero length */
ARGON2_SALT_PTR_MISMATCH = 19, /* NULL ptr with non-zero length */
ARGON2_SECRET_PTR_MISMATCH = 20, /* NULL ptr with non-zero length */
ARGON2_AD_PTR_MISMATCH = 21, /* NULL ptr with non-zero length */
ARGON2_MEMORY_ALLOCATION_ERROR = 22,
@ -122,12 +125,12 @@ typedef enum _Argon2_ErrorCodes {
ARGON2_ERROR_CODES_LENGTH /* Do NOT remove; Do NOT add error codes after
this
error code */
} Argon2_ErrorCodes;
} argon2_error_codes;
/* Memory allocator types --- for external allocation */
typedef int (*AllocateMemoryCallback)(uint8_t **memory,
typedef int (*allocate_fptr)(uint8_t **memory,
size_t bytes_to_allocate);
typedef void (*FreeMemoryCallback)(uint8_t *memory, size_t bytes_to_allocate);
typedef void (*deallocate_fptr)(uint8_t *memory, size_t bytes_to_allocate);
/* Argon2 external data structures */
@ -155,39 +158,32 @@ typedef void (*FreeMemoryCallback)(uint8_t *memory, size_t bytes_to_allocate);
Then you initialize
Argon2_Context(out,8,pwd,32,salt,16,NULL,0,NULL,0,5,1<<20,4,4,NULL,NULL,true,false,false,false).
*/
typedef struct _Argon2_Context {
uint8_t *out; // output array
uint32_t outlen; // digest length
typedef struct Argon2_Context {
uint8_t *out; /* output array */
uint32_t outlen; /* digest length */
uint8_t *pwd; // password array
uint32_t pwdlen; // password length
uint8_t *pwd; /* password array */
uint32_t pwdlen; /* password length */
uint8_t *salt; // salt array
uint32_t saltlen; // salt length
uint8_t *salt; /* salt array */
uint32_t saltlen; /* salt length */
uint8_t *secret; // key array
uint32_t secretlen; // key length
uint8_t *secret; /* key array */
uint32_t secretlen; /* key length */
uint8_t *ad; // associated data array
uint32_t adlen; // associated data length
uint8_t *ad; /* associated data array */
uint32_t adlen; /* associated data length */
uint32_t t_cost; // number of passes
uint32_t m_cost; // amount of memory requested (KB)
uint32_t lanes; // number of lanes
uint32_t threads; // maximum number of threads
uint32_t t_cost; /* number of passes */
uint32_t m_cost; /* amount of memory requested (KB) */
uint32_t lanes; /* number of lanes */
uint32_t threads; /* maximum number of threads */
AllocateMemoryCallback allocate_cbk; // pointer to memory allocator
FreeMemoryCallback free_cbk; // pointer to memory deallocator
allocate_fptr allocate_cbk; /* pointer to memory allocator */
deallocate_fptr free_cbk; /* pointer to memory deallocator */
bool clear_password; // whether to clear the password array
bool clear_secret; // whether to clear the secret array
bool clear_memory; // whether to clear the memory after the run
bool print; // whether to print starting variables, memory blocks, and the
// tag
// to the file -- Test vectors only!
} Argon2_Context;
uint32_t flags; /* array of bool options */
} argon2_context;
/**
* Function to hash the inputs in the memory-hard fashion (uses Argon2i)
@ -218,7 +214,7 @@ int hash_argon2d(void *out, size_t outlen, const void *in, size_t inlen,
* @param context Pointer to current Argon2 context
* @return Zero if successful, a non zero error code otherwise
*/
int argon2d(Argon2_Context *context);
int argon2d(argon2_context *context);
/*
* * **************Argon2i: Version of Argon2 that picks memory blocks
@ -228,14 +224,14 @@ int argon2d(Argon2_Context *context);
* @param context Pointer to current Argon2 context
* @return Zero if successful, a non zero error code otherwise
*/
int argon2i(Argon2_Context *context);
int argon2i(argon2_context *context);
/*
* * **************Argon2di: Reserved name***************
* @param context Pointer to current Argon2 context
* @return Zero if successful, a non zero error code otherwise
*/
int argon2di(Argon2_Context *context);
int argon2di(argon2_context *context);
/*
* * **************Argon2ds: Argon2d hardened against GPU attacks, 20%
@ -243,7 +239,7 @@ int argon2di(Argon2_Context *context);
* @param context Pointer to current Argon2 context
* @return Zero if successful, a non zero error code otherwise
*/
int argon2ds(Argon2_Context *context);
int argon2ds(argon2_context *context);
/*
* * **************Argon2id: First half-pass over memory is
@ -253,7 +249,7 @@ int argon2ds(Argon2_Context *context);
* @param context Pointer to current Argon2 context
* @return Zero if successful, a non zero error code otherwise
*/
int argon2id(Argon2_Context *context);
int argon2id(argon2_context *context);
/*
* Verify if a given password is correct for Argon2d hashing
@ -262,7 +258,7 @@ int argon2id(Argon2_Context *context);
* specified by the context outlen member
* @return Zero if successful, a non zero error code otherwise
*/
int verify_d(Argon2_Context *context, const char *hash);
int verify_d(argon2_context *context, const char *hash);
/*
* Get the associated error message for given error code

View File

@ -41,17 +41,17 @@ enum blake2b_constant {
#pragma pack(push, 1)
typedef struct __blake2b_param {
uint8_t digest_length; // 1
uint8_t key_length; // 2
uint8_t fanout; // 3
uint8_t depth; // 4
uint32_t leaf_length; // 8
uint64_t node_offset; // 16
uint8_t node_depth; // 17
uint8_t inner_length; // 18
uint8_t reserved[14]; // 32
uint8_t salt[BLAKE2B_SALTBYTES]; // 48
uint8_t personal[BLAKE2B_PERSONALBYTES]; // 64
uint8_t digest_length; /* 1 */
uint8_t key_length; /* 2 */
uint8_t fanout; /* 3 */
uint8_t depth; /* 4 */
uint32_t leaf_length; /* 8 */
uint64_t node_offset; /* 16 */
uint8_t node_depth; /* 17 */
uint8_t inner_length; /* 18 */
uint8_t reserved[14]; /* 32 */
uint8_t salt[BLAKE2B_SALTBYTES]; /* 48 */
uint8_t personal[BLAKE2B_PERSONALBYTES]; /* 64 */
} blake2b_param;
ALIGN(64) typedef struct __blake2b_state {

View File

@ -21,9 +21,11 @@
#include "blake2-impl.h"
static const uint64_t blake2b_IV[8] = {
0x6a09e667f3bcc908ULL, 0xbb67ae8584caa73bULL, 0x3c6ef372fe94f82bULL,
0xa54ff53a5f1d36f1ULL, 0x510e527fade682d1ULL, 0x9b05688c2b3e6c1fULL,
0x1f83d9abfb41bd6bULL, 0x5be0cd19137e2179ULL};
UINT64_C(0x6a09e667f3bcc908), UINT64_C(0xbb67ae8584caa73b),
UINT64_C(0x3c6ef372fe94f82b), UINT64_C(0xa54ff53a5f1d36f1),
UINT64_C(0x510e527fade682d1), UINT64_C(0x9b05688c2b3e6c1f),
UINT64_C(0x1f83d9abfb41bd6b), UINT64_C(0x5be0cd19137e2179)
};
static const uint8_t blake2b_sigma[12][16] = {
{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15},
@ -40,7 +42,7 @@ static const uint8_t blake2b_sigma[12][16] = {
{14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3}};
static __inline int blake2b_set_lastnode(blake2b_state *S) {
S->f[1] = ~0ULL;
S->f[1] = ~UINT64_C(0);
return 0;
}
@ -49,7 +51,7 @@ static __inline int blake2b_set_lastblock(blake2b_state *S) {
if (S->last_node)
blake2b_set_lastnode(S);
S->f[0] = ~0ULL;
S->f[0] = ~UINT64_C(0);
return 0;
}
@ -61,9 +63,9 @@ static __inline int blake2b_increment_counter(blake2b_state *S,
}
static __inline int blake2b_init0(blake2b_state *S) {
int i;
memset(S, 0, sizeof(blake2b_state));
for (int i = 0; i < 8; ++i)
for (i = 0; i < 8; ++i)
S->h[i] = blake2b_IV[i];
return 0;
@ -71,11 +73,12 @@ static __inline int blake2b_init0(blake2b_state *S) {
/* init xors IV with input parameter block */
int blake2b_init_param(blake2b_state *S, const blake2b_param *P) {
blake2b_init0(S);
const uint8_t *p = (const uint8_t *)(P);
int i;
blake2b_init0(S);
/* IV XOR ParamBlock */
for (size_t i = 0; i < 8; ++i)
for (i = 0; i < 8; ++i)
S->h[i] ^= load64(p + sizeof(S->h[i]) * i);
return 0;
@ -207,19 +210,19 @@ int blake2b_update(blake2b_state *S, const uint8_t *in, uint64_t inlen) {
size_t fill = 2 * BLAKE2B_BLOCKBYTES - left;
if (inlen > fill) {
memcpy(S->buf + left, in, fill); // Fill buffer
memcpy(S->buf + left, in, fill); /* Fill buffer */
S->buflen += fill;
blake2b_increment_counter(S, BLAKE2B_BLOCKBYTES);
blake2b_compress(S, S->buf); // Compress
blake2b_compress(S, S->buf); /* Compress */
memcpy(S->buf, S->buf + BLAKE2B_BLOCKBYTES,
BLAKE2B_BLOCKBYTES); // Shift buffer left
BLAKE2B_BLOCKBYTES); /* Shift buffer left */
S->buflen -= BLAKE2B_BLOCKBYTES;
in += fill;
inlen -= fill;
} else // inlen <= fill
} else /* inlen <= fill */
{
memcpy(S->buf + left, in, inlen);
S->buflen += inlen; // Be lazy, do not compress
S->buflen += inlen; /* Be lazy, do not compress */
in += inlen;
inlen -= inlen;
}
@ -231,6 +234,7 @@ int blake2b_update(blake2b_state *S, const uint8_t *in, uint64_t inlen) {
/* Is this correct? */
int blake2b_final(blake2b_state *S, uint8_t *out, uint8_t outlen) {
uint8_t buffer[BLAKE2B_OUTBYTES] = {0};
int i;
if (outlen > BLAKE2B_OUTBYTES)
return -1;
@ -248,7 +252,7 @@ int blake2b_final(blake2b_state *S, uint8_t *out, uint8_t outlen) {
2 * BLAKE2B_BLOCKBYTES - S->buflen); /* Padding */
blake2b_compress(S, S->buf);
for (int i = 0; i < 8; ++i) /* Output full hash to temp buffer */
for (i = 0; i < 8; ++i) /* Output full hash to temp buffer */
store64(buffer + sizeof(S->h[i]) * i, S->h[i]);
memcpy(out, buffer, outlen);
@ -302,6 +306,7 @@ int blake2b_long(uint8_t *out, const void *in, const uint32_t outlen,
blake2b_update(&blake_state, (const uint8_t *)in, inlen);
blake2b_final(&blake_state, out, outlen);
} else {
uint32_t toproduce;
uint8_t out_buffer[BLAKE2B_OUTBYTES];
uint8_t in_buffer[BLAKE2B_OUTBYTES];
blake2b_init(&blake_state, BLAKE2B_OUTBYTES);
@ -311,7 +316,7 @@ int blake2b_long(uint8_t *out, const void *in, const uint32_t outlen,
blake2b_final(&blake_state, out_buffer, BLAKE2B_OUTBYTES);
memcpy(out, out_buffer, BLAKE2B_OUTBYTES / 2);
out += BLAKE2B_OUTBYTES / 2;
uint32_t toproduce = outlen - BLAKE2B_OUTBYTES / 2;
toproduce = outlen - BLAKE2B_OUTBYTES / 2;
while (toproduce > BLAKE2B_OUTBYTES) {
memcpy(in_buffer, out_buffer, BLAKE2B_OUTBYTES);

View File

@ -11,7 +11,7 @@
: _mm_xor_si128(_mm_srli_epi64((x), -(c)), \
_mm_slli_epi64((x), 64 - (-(c))))
static inline __m128i fBlaMka(__m128i x, __m128i y) {
static __inline __m128i fBlaMka(__m128i x, __m128i y) {
const __m128i z = _mm_mul_epu32(x, y);
return _mm_add_epi64(_mm_add_epi64(x, y), _mm_add_epi64(z, z));
}

View File

@ -31,9 +31,7 @@ static __inline uint64_t fBlaMka(uint64_t x, uint64_t y) {
lessZ = lessZ * lessY;
lessZ = lessZ << 1;
uint64_t z = lessZ + x + y;
return z;
return lessZ + x + y;
}
#endif

View File

@ -14,7 +14,7 @@
/*For memory wiping*/
#ifdef _MSC_VER
#include <windows.h>
#include <winbase.h> //For SecureZeroMemory
#include <winbase.h> /* For SecureZeroMemory */
#endif
#if defined __STDC_LIB_EXT1__
#define __STDC_WANT_LIB_EXT1__ 1
@ -49,7 +49,7 @@
#endif
/***************Instance and Position constructors**********/
void init_block_value(block *b, uint8_t in) {
void init_block_value(block *b, uint8_t in) {
memset(b->v, in, sizeof(b->v));
}
@ -58,7 +58,8 @@ void copy_block(block *dst, const block *src) {
}
void xor_block(block *dst, const block *src) {
for (int i = 0; i < ARGON2_WORDS_IN_BLOCK; ++i) {
int i;
for (i = 0; i < ARGON2_WORDS_IN_BLOCK; ++i) {
dst->v[i] ^= src->v[i];
}
}
@ -78,8 +79,9 @@ int allocate_memory(block **memory, uint32_t m_cost) {
}
return ARGON2_OK;
} else
} else {
return ARGON2_MEMORY_ALLOCATION_ERROR;
}
}
void NOT_OPTIMIZED secure_wipe_memory(void *v, size_t n) {
@ -97,7 +99,7 @@ void NOT_OPTIMIZED secure_wipe_memory(void *v, size_t n) {
/*********Memory functions*/
void clear_memory(Argon2_instance_t *instance, bool clear) {
void clear_memory(argon2_instance_t *instance, int clear) {
if (instance->memory != NULL && clear) {
secure_wipe_memory(instance->memory,
sizeof(block) * instance->memory_blocks);
@ -105,37 +107,36 @@ void clear_memory(Argon2_instance_t *instance, bool clear) {
}
void free_memory(block *memory) {
if (memory != NULL) {
free(memory);
}
free(memory);
}
void finalize(const Argon2_Context *context, Argon2_instance_t *instance) {
void finalize(const argon2_context *context, argon2_instance_t *instance) {
if (context != NULL && instance != NULL) {
block blockhash;
uint32_t l;
copy_block(&blockhash, instance->memory + instance->lane_length - 1);
// XOR the last blocks
for (uint32_t l = 1; l < instance->lanes; ++l) {
/* XOR the last blocks */
for (l = 1; l < instance->lanes; ++l) {
uint32_t last_block_in_lane =
l * instance->lane_length + (instance->lane_length - 1);
xor_block(&blockhash, instance->memory + last_block_in_lane);
}
// Hash the result
/* Hash the result */
blake2b_long(context->out, (uint8_t *)blockhash.v, context->outlen,
ARGON2_BLOCK_SIZE);
secure_wipe_memory(blockhash.v, ARGON2_BLOCK_SIZE); // clear blockhash
secure_wipe_memory(blockhash.v, ARGON2_BLOCK_SIZE); /* clear blockhash */
if (context->print) // Shall we print the output tag?
if (context->flags & ARGON2_PRINT) /* Shall we print the output tag? */
{
print_tag(context->out, context->outlen);
}
// Clear memory
clear_memory(instance, context->clear_memory);
/* Clear memory */
clear_memory(instance, context->flags & ARGON2_CLEAR_PASSWORD);
// Deallocate the memory
/* Deallocate the memory */
if (NULL != context->free_cbk) {
context->free_cbk((uint8_t *)instance->memory,
instance->memory_blocks * sizeof(block));
@ -145,9 +146,9 @@ void finalize(const Argon2_Context *context, Argon2_instance_t *instance) {
}
}
uint32_t index_alpha(const Argon2_instance_t *instance,
const Argon2_position_t *position, uint32_t pseudo_rand,
bool same_lane) {
uint32_t index_alpha(const argon2_instance_t *instance,
const argon2_position_t *position, uint32_t pseudo_rand,
int same_lane) {
/*
* Pass 0:
* This lane : all already finished segments plus already constructed
@ -159,15 +160,17 @@ uint32_t index_alpha(const Argon2_instance_t *instance,
* Other lanes : (SYNC_POINTS - 1) last segments
*/
uint32_t reference_area_size;
uint64_t relative_position;
uint32_t start_position, absolute_position;
if (0 == position->pass) {
// First pass
/* First pass */
if (0 == position->slice) {
// First slice
reference_area_size = position->index - 1; // all but the previous
/* First slice */
reference_area_size = position->index - 1; /* all but the previous */
} else {
if (same_lane) {
// The same lane => add current segment
/* The same lane => add current segment */
reference_area_size =
position->slice * instance->segment_length +
position->index - 1;
@ -178,7 +181,7 @@ uint32_t index_alpha(const Argon2_instance_t *instance,
}
}
} else {
// Second pass
/* Second pass */
if (same_lane) {
reference_area_size = instance->lane_length -
instance->segment_length + position->index -
@ -192,13 +195,13 @@ uint32_t index_alpha(const Argon2_instance_t *instance,
/* 1.2.4. Mapping pseudo_rand to 0..<reference_area_size-1> and produce
* relative position */
uint64_t relative_position = pseudo_rand;
relative_position = pseudo_rand;
relative_position = relative_position * relative_position >> 32;
relative_position = reference_area_size - 1 -
(reference_area_size * relative_position >> 32);
/* 1.2.5 Computing starting position */
uint32_t start_position = 0;
start_position = 0;
if (0 != position->pass) {
start_position = (position->slice == ARGON2_SYNC_POINTS - 1)
@ -207,8 +210,8 @@ uint32_t index_alpha(const Argon2_instance_t *instance,
}
/* 1.2.6. Computing absolute position */
uint32_t absolute_position = (start_position + relative_position) %
instance->lane_length; // absolute position
absolute_position = (start_position + relative_position) %
instance->lane_length; /* absolute position */
return absolute_position;
}
@ -218,29 +221,34 @@ static DWORD WINAPI fill_segment_thr(void *thread_data)
static void *fill_segment_thr(void *thread_data)
#endif
{
Argon2_thread_data *my_data = (Argon2_thread_data *)thread_data;
argon2_thread_data *my_data = (argon2_thread_data *)thread_data;
fill_segment(my_data->instance_ptr, my_data->pos);
argon2_thread_exit();
return 0;
}
void fill_memory_blocks(Argon2_instance_t *instance) {
void fill_memory_blocks(argon2_instance_t *instance) {
uint32_t r, s;
if (instance == NULL) {
return;
}
for (uint32_t r = 0; r < instance->passes; ++r) {
for (uint8_t s = 0; s < ARGON2_SYNC_POINTS; ++s) {
// 1. Allocating space for threads
for (r = 0; r < instance->passes; ++r) {
for (s = 0; s < ARGON2_SYNC_POINTS; ++s) {
/* 1. Allocating space for threads */
argon2_thread_handle_t *thread =
malloc(sizeof(argon2_thread_handle_t) * (instance->lanes));
Argon2_thread_data *thr_data =
malloc(sizeof(Argon2_thread_data) * (instance->lanes));
argon2_thread_data *thr_data =
malloc(sizeof(argon2_thread_data) * (instance->lanes));
int rc;
uint32_t l;
// 2. Calling threads
for (uint32_t l = 0; l < instance->lanes; ++l) {
// 2.1 Join a thread if limit is exceeded
/* 2. Calling threads */
for (l = 0; l < instance->lanes; ++l) {
argon2_position_t position;
/* 2.1 Join a thread if limit is exceeded */
if (l >= instance->threads) {
rc = argon2_thread_join(thread[l - instance->threads]);
if (rc) {
@ -251,12 +259,15 @@ void fill_memory_blocks(Argon2_instance_t *instance) {
}
}
// 2.2 Create thread
Argon2_position_t position = {r, l, s, 0};
/* 2.2 Create thread */
position.pass = r;
position.lane = l;
position.slice = s;
position.index = 0;
thr_data[l].instance_ptr =
instance; // preparing the thread input
instance; /* preparing the thread input */
memcpy(&(thr_data[l].pos), &position,
sizeof(Argon2_position_t));
sizeof(argon2_position_t));
rc = argon2_thread_create(&thread[l], fill_segment_thr,
(void *)&thr_data[l]);
if (rc) {
@ -266,13 +277,12 @@ void fill_memory_blocks(Argon2_instance_t *instance) {
exit(-1);
}
// FillSegment(instance, position); //Non-thread equivalent of
// the
// lines above
/* FillSegment(instance, position); */
/*Non-thread equivalent of the lines above */
}
// 3. Joining remaining threads
for (uint32_t l = instance->lanes - instance->threads;
/* 3. Joining remaining threads */
for (l = instance->lanes - instance->threads;
l < instance->lanes; ++l) {
rc = argon2_thread_join(thread[l]);
if (rc) {
@ -287,12 +297,12 @@ void fill_memory_blocks(Argon2_instance_t *instance) {
}
if (instance->print_internals) {
internal_kat(instance, r); // Print all memory blocks
internal_kat(instance, r); /* Print all memory blocks */
}
}
}
int validate_inputs(const Argon2_Context *context) {
int validate_inputs(const argon2_context *context) {
if (NULL == context) {
return ARGON2_INCORRECT_PARAMETER;
}
@ -380,8 +390,8 @@ int validate_inputs(const Argon2_Context *context) {
return ARGON2_MEMORY_TOO_MUCH;
}
if (sizeof(uint32_t *) == 4) { // 32-bit machine
if (ARGON2_32BIT_LIMIT < context->m_cost) { // 2^21 blocks (2 GB) maximum
if (sizeof(uint32_t *) == 4) { /* 32-bit machine */
if (ARGON2_32BIT_LIMIT < context->m_cost) { /* 2^21 blocks (2 GB) maximum */
return ARGON2_MEMORY_TOO_MUCH;
}
}
@ -424,10 +434,11 @@ int validate_inputs(const Argon2_Context *context) {
return ARGON2_OK;
}
void fill_first_blocks(uint8_t *blockhash, const Argon2_instance_t *instance) {
// Make the first and second block in each lane as G(H0||i||0) or
// G(H0||i||1)
for (uint32_t l = 0; l < instance->lanes; ++l) {
void fill_first_blocks(uint8_t *blockhash, const argon2_instance_t *instance) {
uint32_t l;
/* Make the first and second block in each lane as G(H0||i||0) or
G(H0||i||1) */
for (l = 0; l < instance->lanes; ++l) {
store32(blockhash + ARGON2_PREHASH_DIGEST_LENGTH, 0);
store32(blockhash + ARGON2_PREHASH_DIGEST_LENGTH + 4, l);
blake2b_long((uint8_t *)(instance->memory[l * instance->lane_length].v),
@ -440,8 +451,8 @@ void fill_first_blocks(uint8_t *blockhash, const Argon2_instance_t *instance) {
}
}
void initial_hash(uint8_t *blockhash, Argon2_Context *context,
Argon2_type type) {
void initial_hash(uint8_t *blockhash, argon2_context *context,
argon2_type type) {
blake2b_state BlakeHash;
uint8_t value[sizeof(uint32_t)];
@ -476,7 +487,7 @@ void initial_hash(uint8_t *blockhash, Argon2_Context *context,
blake2b_update(&BlakeHash, (const uint8_t *)context->pwd,
context->pwdlen);
if (context->clear_password) {
if (context->flags & ARGON2_CLEAR_PASSWORD) {
secure_wipe_memory(context->pwd, context->pwdlen);
context->pwdlen = 0;
}
@ -497,7 +508,7 @@ void initial_hash(uint8_t *blockhash, Argon2_Context *context,
blake2b_update(&BlakeHash, (const uint8_t *)context->secret,
context->secretlen);
if (context->clear_secret) {
if (context->flags & ARGON2_CLEAR_SECRET) {
secure_wipe_memory(context->secret, context->secretlen);
context->secretlen = 0;
}
@ -514,12 +525,14 @@ void initial_hash(uint8_t *blockhash, Argon2_Context *context,
blake2b_final(&BlakeHash, blockhash, ARGON2_PREHASH_DIGEST_LENGTH);
}
int initialize(Argon2_instance_t *instance, Argon2_Context *context) {
int initialize(argon2_instance_t *instance, argon2_context *context) {
uint8_t blockhash[ARGON2_PREHASH_SEED_LENGTH];
int result = ARGON2_OK;
if (instance == NULL || context == NULL)
return ARGON2_INCORRECT_PARAMETER;
// 1. Memory allocation
int result = ARGON2_OK;
/* 1. Memory allocation */
if (NULL != context->allocate_cbk) {
result =
@ -533,31 +546,33 @@ int initialize(Argon2_instance_t *instance, Argon2_Context *context) {
return result;
}
// 2. Initial hashing
// H_0 + 8 extra bytes to produce the first blocks
uint8_t blockhash[ARGON2_PREHASH_SEED_LENGTH];
// Hashing all inputs
/* 2. Initial hashing */
/* H_0 + 8 extra bytes to produce the first blocks */
/* uint8_t blockhash[ARGON2_PREHASH_SEED_LENGTH]; */
/* Hashing all inputs */
initial_hash(blockhash, context, instance->type);
// Zeroing 8 extra bytes
/* Zeroing 8 extra bytes */
secure_wipe_memory(blockhash + ARGON2_PREHASH_DIGEST_LENGTH,
ARGON2_PREHASH_SEED_LENGTH -
ARGON2_PREHASH_DIGEST_LENGTH);
if (context->print) {
if (context->flags & ARGON2_PRINT) {
initial_kat(blockhash, context, instance->type);
}
// 3. Creating first blocks, we always have at least two blocks in a slice
/* 3. Creating first blocks, we always have at least two blocks in a slice */
fill_first_blocks(blockhash, instance);
// Clearing the hash
/* Clearing the hash */
secure_wipe_memory(blockhash, ARGON2_PREHASH_SEED_LENGTH);
return ARGON2_OK;
}
int argon2_core(Argon2_Context *context, Argon2_type type) {
int argon2_core(argon2_context *context, argon2_type type) {
/* 1. Validate all inputs */
int result = validate_inputs(context);
uint32_t memory_blocks, segment_length;
argon2_instance_t instance;
if (ARGON2_OK != result) {
return result;
@ -568,27 +583,26 @@ int argon2_core(Argon2_Context *context, Argon2_type type) {
}
/* 2. Align memory size */
// Minimum memory_blocks = 8L blocks, where L is the number of lanes
uint32_t memory_blocks = context->m_cost;
/* Minimum memory_blocks = 8L blocks, where L is the number of lanes */
memory_blocks = context->m_cost;
if (memory_blocks < 2 * ARGON2_SYNC_POINTS * context->lanes) {
memory_blocks = 2 * ARGON2_SYNC_POINTS * context->lanes;
}
uint32_t segment_length =
memory_blocks / (context->lanes * ARGON2_SYNC_POINTS);
bool print_internals = context->print;
// Ensure that all segments have equal length
segment_length = memory_blocks / (context->lanes * ARGON2_SYNC_POINTS);
/* Ensure that all segments have equal length */
memory_blocks = segment_length * (context->lanes * ARGON2_SYNC_POINTS);
Argon2_instance_t instance = {NULL,
context->t_cost,
memory_blocks,
segment_length,
segment_length * ARGON2_SYNC_POINTS,
context->lanes,
context->threads,
type,
print_internals};
instance.memory = NULL;
instance.passes = context->t_cost;
instance.memory_blocks = memory_blocks;
instance.segment_length = segment_length;
instance.lane_length = segment_length * ARGON2_SYNC_POINTS;
instance.lanes = context->lanes;
instance.threads = context->threads;
instance.type = type;
instance.print_internals = !!(context->flags & ARGON2_PRINT);
/* 3. Initialization: Hashing inputs, allocating memory, filling first
* blocks

View File

@ -14,10 +14,12 @@
#ifndef ARGON2_CORE_H
#define ARGON2_CORE_H
#include "blake2/blake2.h"
/*************************Argon2 internal
* constants**************************************************/
enum Argon2_core_constants {
enum argon2_core_constants {
/* Version of the algorithm */
ARGON2_VERSION_NUMBER = 0x10,
@ -37,10 +39,10 @@ enum Argon2_core_constants {
};
/* Argon2 primitive type */
typedef enum _Argon2_type {
typedef enum Argon2_type {
Argon2_d = 0,
Argon2_i = 1,
} Argon2_type;
Argon2_i = 1
} argon2_type;
/*************************Argon2 internal data
* types**************************************************/
@ -50,25 +52,19 @@ typedef enum _Argon2_type {
* Memory blocks can be copied, XORed. Internal words can be accessed by [] (no
* bounds checking).
*/
#ifndef _MSC_VER
typedef struct _block {
uint64_t v[ARGON2_WORDS_IN_BLOCK];
} __attribute__((aligned(16))) block;
#else
typedef struct _block {
uint64_t v[ARGON2_WORDS_IN_BLOCK];
} __declspec(align(16)) block;
#endif
} ALIGN(16) block;
/*****************Functions that work with the block******************/
// Initialize each byte of the block with @in
/* Initialize each byte of the block with @in */
void init_block_value(block *b, uint8_t in);
// Copy block @src to block @dst
/* Copy block @src to block @dst */
void copy_block(block *dst, const block *src);
// XOR @src onto @dst bytewise
/* XOR @src onto @dst bytewise */
void xor_block(block *dst, const block *src);
/*
@ -77,42 +73,34 @@ void xor_block(block *dst, const block *src);
* Used to evaluate the number and location of blocks to construct in each
* thread
*/
typedef struct _Argon2_instance_t {
block *memory; // Memory pointer
const uint32_t passes; // Number of passes
const uint32_t memory_blocks; // Number of blocks in memory
const uint32_t segment_length;
const uint32_t lane_length;
const uint32_t lanes;
const uint32_t threads;
const Argon2_type type;
const bool print_internals; // whether to print the memory blocks
} Argon2_instance_t;
typedef struct Argon2_instance_t {
block *memory; /* Memory pointer */
uint32_t passes; /* Number of passes */
uint32_t memory_blocks; /* Number of blocks in memory */
uint32_t segment_length;
uint32_t lane_length;
uint32_t lanes;
uint32_t threads;
argon2_type type;
int print_internals; /* whether to print the memory blocks */
} argon2_instance_t;
/*
* Argon2 position: where we construct the block right now. Used to distribute
* work between threads.
*/
typedef struct _Argon2_position_t {
const uint32_t pass;
const uint32_t lane;
const uint8_t slice;
typedef struct Argon2_position_t {
uint32_t pass;
uint32_t lane;
uint8_t slice;
uint32_t index;
} Argon2_position_t;
} argon2_position_t;
/*Struct that holds the inputs for thread handling FillSegment*/
typedef struct _Argon2_thread_data {
Argon2_instance_t *instance_ptr;
Argon2_position_t pos;
} Argon2_thread_data;
/*Macro for endianness conversion*/
#if defined(_MSC_VER)
#define BSWAP32(x) _byteswap_ulong(x)
#else
#define BSWAP32(x) __builtin_bswap32(x)
#endif
typedef struct Argon2_thread_data {
argon2_instance_t *instance_ptr;
argon2_position_t pos;
} argon2_thread_data;
/*************************Argon2 core
* functions**************************************************/
@ -134,7 +122,7 @@ void secure_wipe_memory(void *v, size_t n);
* @param instance pointer to the current instance
* @param clear_memory indicates if we clear the memory with zeros.
*/
void clear_memory(Argon2_instance_t *instance, bool clear);
void clear_memory(argon2_instance_t *instance, int clear);
/* Deallocates memory
* @param memory pointer to the blocks
@ -151,9 +139,9 @@ void free_memory(block *memory);
* If so we can reference the current segment
* @pre All pointers must be valid
*/
uint32_t index_alpha(const Argon2_instance_t *instance,
const Argon2_position_t *position, uint32_t pseudo_rand,
bool same_lane);
uint32_t index_alpha(const argon2_instance_t *instance,
const argon2_position_t *position, uint32_t pseudo_rand,
int same_lane);
/*
* Function that validates all inputs against predefined restrictions and return
@ -162,7 +150,7 @@ uint32_t index_alpha(const Argon2_instance_t *instance,
* @return ARGON2_OK if everything is all right, otherwise one of error codes
* (all defined in <argon2.h>
*/
int validate_inputs(const Argon2_Context *context);
int validate_inputs(const argon2_context *context);
/*
* Hashes all the inputs into @a blockhash[PREHASH_DIGEST_LENGTH], clears
@ -174,8 +162,8 @@ int validate_inputs(const Argon2_Context *context);
* @pre @a blockhash must have at least @a PREHASH_DIGEST_LENGTH bytes
* allocated
*/
void initial_hash(uint8_t *blockhash, Argon2_Context *context,
Argon2_type type);
void initial_hash(uint8_t *blockhash, argon2_context *context,
argon2_type type);
/*
* Function creates first 2 blocks per lane
@ -183,7 +171,7 @@ void initial_hash(uint8_t *blockhash, Argon2_Context *context,
* @param blockhash Pointer to the pre-hashing digest
* @pre blockhash must point to @a PREHASH_SEED_LENGTH allocated values
*/
void fill_firsts_blocks(uint8_t *blockhash, const Argon2_instance_t *instance);
void fill_firsts_blocks(uint8_t *blockhash, const argon2_instance_t *instance);
/*
* Function allocates memory, hashes the inputs with Blake, and creates first
@ -195,7 +183,7 @@ void fill_firsts_blocks(uint8_t *blockhash, const Argon2_instance_t *instance);
* @return Zero if successful, -1 if memory failed to allocate. @context->state
* will be modified if successful.
*/
int initialize(Argon2_instance_t *instance, Argon2_Context *context);
int initialize(argon2_instance_t *instance, argon2_context *context);
/*
* XORing the last block of each lane, hashing it, making the tag. Deallocates
@ -208,7 +196,7 @@ int initialize(Argon2_instance_t *instance, Argon2_Context *context);
* @pre if context->free_cbk is not NULL, it should point to a function that
* deallocates memory
*/
void finalize(const Argon2_Context *context, Argon2_instance_t *instance);
void finalize(const argon2_context *context, argon2_instance_t *instance);
/*
* Function that fills the segment using previous segments also from other
@ -217,21 +205,21 @@ void finalize(const Argon2_Context *context, Argon2_instance_t *instance);
* @param position Current position
* @pre all block pointers must be valid
*/
void fill_segment(const Argon2_instance_t *instance,
Argon2_position_t position);
void fill_segment(const argon2_instance_t *instance,
argon2_position_t position);
/*
* Function that fills the entire memory t_cost times based on the first two
* blocks in each lane
* @param instance Pointer to the current instance
*/
void fill_memory_blocks(Argon2_instance_t *instance);
void fill_memory_blocks(argon2_instance_t *instance);
/*
* Function that performs memory-hard hashing with certain degree of parallelism
* @param context Pointer to the Argon2 internal structure
* @return Error code if smth is wrong, ARGON2_OK otherwise
*/
int argon2_core(Argon2_Context *context, Argon2_type type);
int argon2_core(argon2_context *context, argon2_type type);
#endif

View File

@ -104,7 +104,7 @@ static size_t to_base64(char *dst, size_t dst_len, const void *src,
* The output length is always exactly 32 bytes.
*/
int encode_string(char *dst, size_t dst_len, Argon2_Context *ctx) {
int encode_string(char *dst, size_t dst_len, argon2_context *ctx) {
#define SS(str) \
do { \
size_t pp_len = strlen(str); \

View File

@ -18,8 +18,9 @@
#include "argon2.h"
#include "core.h"
void initial_kat(const uint8_t *blockhash, const Argon2_Context *context,
Argon2_type type) {
void initial_kat(const uint8_t *blockhash, const argon2_context *context,
argon2_type type) {
unsigned i;
FILE *fp = fopen(ARGON2_KAT_FILENAME, "a+");
if (fp && blockhash != NULL && context != NULL) {
@ -45,10 +46,10 @@ void initial_kat(const uint8_t *blockhash, const Argon2_Context *context,
fprintf(fp, "Password[%d]: ", context->pwdlen);
if (context->clear_password) {
if (context->flags & ARGON2_CLEAR_PASSWORD) {
fprintf(fp, "CLEARED\n");
} else {
for (unsigned i = 0; i < context->pwdlen; ++i) {
for (i = 0; i < context->pwdlen; ++i) {
fprintf(fp, "%2.2x ", ((unsigned char *)context->pwd)[i]);
}
@ -57,7 +58,7 @@ void initial_kat(const uint8_t *blockhash, const Argon2_Context *context,
fprintf(fp, "Salt[%d]: ", context->saltlen);
for (unsigned i = 0; i < context->saltlen; ++i) {
for (i = 0; i < context->saltlen; ++i) {
fprintf(fp, "%2.2x ", ((unsigned char *)context->salt)[i]);
}
@ -65,10 +66,10 @@ void initial_kat(const uint8_t *blockhash, const Argon2_Context *context,
fprintf(fp, "Secret[%d]: ", context->secretlen);
if (context->clear_secret) {
if (context->flags & ARGON2_CLEAR_SECRET) {
fprintf(fp, "CLEARED\n");
} else {
for (unsigned i = 0; i < context->secretlen; ++i) {
for (i = 0; i < context->secretlen; ++i) {
fprintf(fp, "%2.2x ", ((unsigned char *)context->secret)[i]);
}
@ -77,7 +78,7 @@ void initial_kat(const uint8_t *blockhash, const Argon2_Context *context,
fprintf(fp, "Associated data[%d]: ", context->adlen);
for (unsigned i = 0; i < context->adlen; ++i) {
for (i = 0; i < context->adlen; ++i) {
fprintf(fp, "%2.2x ", ((unsigned char *)context->ad)[i]);
}
@ -85,7 +86,7 @@ void initial_kat(const uint8_t *blockhash, const Argon2_Context *context,
fprintf(fp, "Pre-hashing digest: ");
for (unsigned i = 0; i < ARGON2_PREHASH_DIGEST_LENGTH; ++i) {
for (i = 0; i < ARGON2_PREHASH_DIGEST_LENGTH; ++i) {
fprintf(fp, "%2.2x ", ((unsigned char *)blockhash)[i]);
}
@ -97,11 +98,11 @@ void initial_kat(const uint8_t *blockhash, const Argon2_Context *context,
void print_tag(const void *out, uint32_t outlen) {
FILE *fp = fopen(ARGON2_KAT_FILENAME, "a+");
unsigned i;
if (fp && out != NULL) {
fprintf(fp, "Tag: ");
for (unsigned i = 0; i < outlen; ++i) {
for (i = 0; i < outlen; ++i) {
fprintf(fp, "%2.2x ", ((uint8_t *)out)[i]);
}
@ -111,19 +112,20 @@ void print_tag(const void *out, uint32_t outlen) {
}
}
void internal_kat(const Argon2_instance_t *instance, uint32_t pass) {
void internal_kat(const argon2_instance_t *instance, uint32_t pass) {
FILE *fp = fopen(ARGON2_KAT_FILENAME, "a+");
if (fp && instance != NULL) {
uint32_t i, j;
fprintf(fp, "\n After pass %d:\n", pass);
for (uint32_t i = 0; i < instance->memory_blocks; ++i) {
for (i = 0; i < instance->memory_blocks; ++i) {
uint32_t how_many_words =
(instance->memory_blocks > ARGON2_WORDS_IN_BLOCK)
? 1
: ARGON2_WORDS_IN_BLOCK;
for (uint32_t j = 0; j < how_many_words; ++j)
for (j = 0; j < how_many_words; ++j)
fprintf(fp, "Block %.4d [%3d]: %016" PRIx64 "\n", i, j,
instance->memory[i].v[j]);
}

View File

@ -23,8 +23,8 @@
* @pre context member pointers must point to allocated memory of size according
* to the length values
*/
void initial_kat(const uint8_t *blockhash, const Argon2_Context *context,
Argon2_type type);
void initial_kat(const uint8_t *blockhash, const argon2_context *context,
argon2_type type);
/*
* Function that prints the output tag
@ -40,6 +40,6 @@ void print_tag(const void *out, uint32_t outlen);
* @param pass current pass number
* @pre instance must have necessary memory allocated
**/
void internal_kat(const Argon2_instance_t *instance, uint32_t pass);
void internal_kat(const argon2_instance_t *instance, uint32_t pass);
#endif

View File

@ -97,7 +97,8 @@ void fatal(const char *error) {
}
void print_bytes(const void *s, size_t len) {
for (size_t i = 0; i < len; i++) {
size_t i;
for (i = 0; i < len; i++) {
printf("%02x", ((const unsigned char *)s)[i] & 0xff);
}
@ -120,35 +121,53 @@ void benchmark() {
#undef BENCH_OUTLEN
uint32_t t_cost = 1;
uint32_t m_cost;
uint32_t thread_test[6] = {1, 2, 4, 6, 8, 16};
memset(pwd_array, 0, inlen);
memset(salt_array, 1, inlen);
uint32_t thread_test[6] = {1, 2, 4, 6, 8, 16};
uint32_t m_cost;
for (m_cost = (uint32_t)1 << 10; m_cost <= (uint32_t)1 << 22; m_cost *= 2) {
for (uint32_t i = 0; i < 6; ++i) {
unsigned i;
for (i = 0; i < 6; ++i) {
argon2_context context;
uint32_t thread_n = thread_test[i];
uint64_t start_cycles, stop_cycles, stop_cycles_i;
uint64_t stop_cycles, stop_cycles_i;
clock_t stop_time;
uint64_t delta_d, delta_i;
double mcycles_d, mcycles_i, run_time;
clock_t start_time = clock();
start_cycles = rdtsc();
uint64_t start_cycles = rdtsc();
context.out = out;
context.outlen = outlen;
context.pwd = pwd_array;
context.pwdlen = inlen;
context.salt = salt_array;
context.saltlen = inlen;
context.secret = NULL;
context.secretlen = 0;
context.ad = NULL;
context.adlen = 0;
context.t_cost = t_cost;
context.m_cost = m_cost;
context.lanes = thread_n;
context.threads = thread_n;
context.allocate_cbk = NULL;
context.free_cbk = NULL;
context.flags = 0;
Argon2_Context context = {
out, outlen, pwd_array, inlen, salt_array, inlen, NULL,
0, NULL, 0, t_cost, m_cost, thread_n, thread_n,
NULL, NULL, false, false, false, false};
argon2d(&context);
stop_cycles = rdtsc();
argon2i(&context);
stop_cycles_i = rdtsc();
clock_t stop_time = clock();
stop_time = clock();
uint64_t delta_d = (stop_cycles - start_cycles) / (m_cost);
uint64_t delta_i = (stop_cycles_i - stop_cycles) / (m_cost);
float mcycles_d = (float)(stop_cycles - start_cycles) / (1 << 20);
float mcycles_i = (float)(stop_cycles_i - stop_cycles) / (1 << 20);
delta_d = (stop_cycles - start_cycles) / (m_cost);
delta_i = (stop_cycles_i - stop_cycles) / (m_cost);
mcycles_d = (double)(stop_cycles - start_cycles) / (1UL << 20);
mcycles_i = (double)(stop_cycles_i - stop_cycles) / (1UL << 20);
printf(
"Argon2d %d pass(es) %d Mbytes %d threads: %2.2f cpb %2.2f "
"Mcycles \n",
@ -160,7 +179,7 @@ void benchmark() {
t_cost, m_cost >> 10, thread_n, (float)delta_i / 1024,
mcycles_i);
float run_time = ((float)stop_time - start_time) / (CLOCKS_PER_SEC);
run_time = ((double)stop_time - start_time) / (CLOCKS_PER_SEC);
printf("%2.4f seconds\n\n", run_time);
}
}
@ -182,20 +201,22 @@ void run(uint8_t *out, char *pwd, uint8_t *salt, uint32_t t_cost,
uint32_t m_cost, uint32_t lanes, uint32_t threads, const char *type) {
uint64_t start_cycles, stop_cycles;
clock_t start_time, stop_time;
start_time = clock();
start_cycles = rdtsc();
double run_time, run_cycles;
/*Fixed parameters*/
const unsigned out_length = 32;
const unsigned salt_length = SALTLEN_DEF;
unsigned pwd_length;
bool clear_memory = false;
bool clear_secret = false;
bool clear_password = true;
unsigned pwd_length;
argon2_context context;
char encoded[300];
if (!pwd)
start_time = clock();
start_cycles = rdtsc();
if (!pwd) {
fatal("password missing");
}
if (!salt) {
secure_wipe_memory(pwd, strlen(pwd));
fatal("salt missing");
@ -205,11 +226,23 @@ void run(uint8_t *out, char *pwd, uint8_t *salt, uint32_t t_cost,
UNUSED_PARAMETER(threads);
Argon2_Context context = {
out, out_length, (uint8_t*)pwd, pwd_length, salt, salt_length,
NULL, 0, NULL, 0, t_cost, m_cost,
lanes, lanes, NULL, NULL, clear_password, clear_secret,
clear_memory, false};
context.out = out;
context.outlen = out_length;
context.pwd = (uint8_t *)pwd;
context.pwdlen = pwd_length;
context.salt = salt;
context.saltlen = salt_length;
context.secret = NULL;
context.secretlen = 0;
context.ad = NULL;
context.adlen = 0;
context.t_cost = t_cost;
context.m_cost = m_cost;
context.lanes = lanes;
context.threads = lanes;
context.allocate_cbk = NULL;
context.free_cbk = NULL;
context.flags = ARGON2_CLEAR_PASSWORD;
if (!strcmp(type, "d")) argon2d(&context);
else if (!strcmp(type, "i")) argon2i(&context);
@ -221,14 +254,13 @@ void run(uint8_t *out, char *pwd, uint8_t *salt, uint32_t t_cost,
stop_cycles = rdtsc();
stop_time = clock();
// show string encoding
char encoded[300];
/* show string encoding */
encode_string(encoded, sizeof encoded, &context);
printf("%s\n", encoded);
// show running time/cycles
float run_time = ((float)stop_time - start_time) / (CLOCKS_PER_SEC);
float run_cycles = (float)(stop_cycles - start_cycles) / (1 << 20);
/* show running time/cycles */
run_time = ((double)stop_time - start_time) / (CLOCKS_PER_SEC);
run_cycles = (double)(stop_cycles - start_cycles) / (1UL << 20);
printf("%2.3f seconds ", run_time);
printf("(%.3f mebicycles)\n", run_cycles);
}
@ -239,18 +271,15 @@ void generate_testvectors(const char *type) {
#define TEST_SALTLEN 16
#define TEST_SECRETLEN 8
#define TEST_ADLEN 12
bool clear_memory = false;
bool clear_secret = false;
bool clear_password = false;
bool print_internals = true;
argon2_context context;
unsigned char out[TEST_OUTLEN];
unsigned char pwd[TEST_PWDLEN];
unsigned char salt[TEST_SALTLEN];
unsigned char secret[TEST_SECRETLEN];
unsigned char ad[TEST_ADLEN];
const AllocateMemoryCallback myown_allocator = NULL;
const FreeMemoryCallback myown_deallocator = NULL;
const allocate_fptr myown_allocator = NULL;
const deallocate_fptr myown_deallocator = NULL;
unsigned t_cost = 3;
unsigned m_cost = 16;
@ -264,26 +293,24 @@ void generate_testvectors(const char *type) {
printf("Generating test vectors for Argon2%s in file \"%s\".\n", type,
ARGON2_KAT_FILENAME);
Argon2_Context context = {out,
TEST_OUTLEN,
pwd,
TEST_PWDLEN,
salt,
TEST_SALTLEN,
secret,
TEST_SECRETLEN,
ad,
TEST_ADLEN,
t_cost,
m_cost,
lanes,
lanes,
myown_allocator,
myown_deallocator,
clear_password,
clear_secret,
clear_memory,
print_internals};
context.out = out;
context.outlen = TEST_OUTLEN;
context.pwd = pwd;
context.pwdlen = TEST_PWDLEN;
context.salt = salt;
context.saltlen = TEST_SALTLEN;
context.secret = secret;
context.secretlen = TEST_SECRETLEN;
context.ad = ad;
context.adlen = TEST_ADLEN;
context.t_cost = t_cost;
context.m_cost = m_cost;
context.lanes = lanes;
context.threads = lanes;
context.allocate_cbk = myown_allocator;
context.free_cbk = myown_deallocator;
context.flags = ARGON2_PRINT;
#undef TEST_OUTLEN
#undef TEST_PWDLEN
#undef TEST_SALTLEN
@ -311,6 +338,7 @@ int main(int argc, char *argv[]) {
char *pwd = NULL;
uint8_t salt[SALTLEN_DEF];
char *type = "i";
int i;
remove(ARGON2_KAT_FILENAME);
@ -331,15 +359,15 @@ int main(int argc, char *argv[]) {
return ARGON2_MISSING_ARGS;
}
// get password and salt from command line
/* get password and salt from command line */
pwd = argv[1];
if (strlen(argv[2]) > SALTLEN_DEF)
fatal("salt too long");
memset(salt, 0x00, SALTLEN_DEF); // pad with null bytes
memset(salt, 0x00, SALTLEN_DEF); /* pad with null bytes */
memcpy(salt, (uint8_t *)argv[2], strlen(argv[2]));
// parse options
for (int i = 3; i < argc; i++) {
/* parse options */
for (i = 3; i < argc; i++) {
char *a = argv[i];
if (!strcmp(a, "-m")) {

View File

@ -43,13 +43,14 @@ const char *ARGON2_KAT_FILENAME = "kat-argon2-opt.log";
void fill_block(__m128i *state, const uint8_t *ref_block, uint8_t *next_block) {
__m128i t0, t1;
__m128i block_XY[ARGON2_QWORDS_IN_BLOCK];
uint32_t i;
for (uint32_t i = 0; i < ARGON2_QWORDS_IN_BLOCK; i++) {
for (i = 0; i < ARGON2_QWORDS_IN_BLOCK; i++) {
block_XY[i] = _mm_loadu_si128((__m128i *)ref_block);
ref_block += 16;
}
for (uint32_t i = 0; i < ARGON2_QWORDS_IN_BLOCK; i++) {
for (i = 0; i < ARGON2_QWORDS_IN_BLOCK; i++) {
block_XY[i] = state[i] = _mm_xor_si128(state[i], block_XY[i]);
}
@ -101,21 +102,23 @@ void fill_block(__m128i *state, const uint8_t *ref_block, uint8_t *next_block) {
BLAKE2_ROUND(state[7], state[15], state[23], state[31], state[39],
state[47], state[55], state[63]);
for (uint32_t i = 0; i < ARGON2_QWORDS_IN_BLOCK; i++) {
// Feedback
for (i = 0; i < ARGON2_QWORDS_IN_BLOCK; i++) {
/* Feedback */
state[i] = _mm_xor_si128(state[i], block_XY[i]);
}
for (uint32_t i = 0; i < ARGON2_QWORDS_IN_BLOCK; i++) {
for (i = 0; i < ARGON2_QWORDS_IN_BLOCK; i++) {
_mm_storeu_si128((__m128i *)next_block, state[i]);
next_block += 16;
}
}
void generate_addresses(const Argon2_instance_t *instance,
const Argon2_position_t *position,
void generate_addresses(const argon2_instance_t *instance,
const argon2_position_t *position,
uint64_t *pseudo_rands) {
block zero_block, address_block, input_block;
uint32_t i;
init_block_value(&zero_block, 0);
copy_block(&address_block, &zero_block);
copy_block(&input_block, &zero_block);
@ -128,10 +131,10 @@ void generate_addresses(const Argon2_instance_t *instance,
input_block.v[4] = instance->passes;
input_block.v[5] = instance->type;
for (uint32_t i = 0; i < instance->segment_length; ++i) {
for (i = 0; i < instance->segment_length; ++i) {
if (i % ARGON2_ADDRESSES_IN_BLOCK == 0) {
input_block.v[6]++;
block zero_block, zero2_block;
input_block.v[6]++;
init_block_value(&zero_block, 0);
init_block_value(&zero2_block, 0);
fill_block((__m128i *)&zero_block.v, (uint8_t *)&input_block.v,
@ -146,49 +149,53 @@ void generate_addresses(const Argon2_instance_t *instance,
}
}
void fill_segment(const Argon2_instance_t *instance,
Argon2_position_t position) {
if (instance == NULL)
return;
void fill_segment(const argon2_instance_t *instance,
argon2_position_t position) {
block * ref_block = NULL, * curr_block = NULL;
uint64_t pseudo_rand, ref_index, ref_lane;
uint32_t prev_offset, curr_offset;
uint32_t starting_index, i;
__m128i state[64];
bool data_independent_addressing = (instance->type == Argon2_i);
int data_independent_addressing = (instance->type == Argon2_i);
// Pseudo-random values that determine the reference block position
uint64_t *pseudo_rands =
(uint64_t *)malloc(sizeof(uint64_t) * instance->segment_length);
/* Pseudo-random values that determine the reference block position */
uint64_t *pseudo_rands = NULL;
if (pseudo_rands == NULL)
if (instance == NULL) {
return;
}
pseudo_rands = (uint64_t *)malloc(sizeof(uint64_t) * instance->segment_length);
if (pseudo_rands == NULL) {
return;
}
if (data_independent_addressing) {
generate_addresses(instance, &position, pseudo_rands);
}
uint32_t starting_index = 0;
starting_index = 0;
if ((0 == position.pass) && (0 == position.slice)) {
starting_index = 2; // we have already generated the first two blocks
starting_index = 2; /* we have already generated the first two blocks */
}
// Offset of the current block
/* Offset of the current block */
curr_offset = position.lane * instance->lane_length +
position.slice * instance->segment_length + starting_index;
if (0 == curr_offset % instance->lane_length) {
// Last block in this lane
/* Last block in this lane */
prev_offset = curr_offset + instance->lane_length - 1;
} else {
// Previous block
/* Previous block */
prev_offset = curr_offset - 1;
}
memcpy(state, (uint8_t *)((instance->memory + prev_offset)->v),
ARGON2_BLOCK_SIZE);
for (uint32_t i = starting_index; i < instance->segment_length;
for (i = starting_index; i < instance->segment_length;
++i, ++curr_offset, ++prev_offset) {
/*1.1 Rotating prev_offset if needed */
if (curr_offset % instance->lane_length == 1) {
@ -207,7 +214,7 @@ void fill_segment(const Argon2_instance_t *instance,
ref_lane = ((pseudo_rand >> 32)) % instance->lanes;
if ((position.pass == 0) && (position.slice == 0)) {
// Can not reference other lanes yet
/* Can not reference other lanes yet */
ref_lane = position.lane;
}
@ -219,9 +226,8 @@ void fill_segment(const Argon2_instance_t *instance,
ref_lane == position.lane);
/* 2 Creating a new block */
block *ref_block =
instance->memory + instance->lane_length * ref_lane + ref_index;
block *curr_block = instance->memory + curr_offset;
ref_block = instance->memory + instance->lane_length * ref_lane + ref_index;
curr_block = instance->memory + curr_offset;
fill_block(state, (uint8_t *)ref_block->v, (uint8_t *)curr_block->v);
}

View File

@ -31,8 +31,8 @@ void fill_block(__m128i *state, const uint8_t *ref_block, uint8_t *next_block);
* @param pseudo_rands Pointer to the array of 64-bit values
* @pre pseudo_rands must point to @a instance->segment_length allocated values
*/
void generate_addresses(const Argon2_instance_t *instance,
const Argon2_position_t *position,
void generate_addresses(const argon2_instance_t *instance,
const argon2_position_t *position,
uint64_t *pseudo_rands);
/*
@ -43,7 +43,7 @@ void generate_addresses(const Argon2_instance_t *instance,
* @param position Current position
* @pre all block pointers must be valid
*/
void fill_segment(const Argon2_instance_t *instance,
Argon2_position_t position);
void fill_segment(const argon2_instance_t *instance,
argon2_position_t position);
#endif /* ARGON2_OPT_H */

View File

@ -29,15 +29,16 @@ const char *ARGON2_KAT_FILENAME = "kat-argon2-ref.log";
void fill_block(const block *prev_block, const block *ref_block,
block *next_block) {
block blockR;
block blockR, block_tmp;
unsigned i;
copy_block(&blockR, ref_block);
xor_block(&blockR, prev_block);
block block_tmp;
copy_block(&block_tmp, &blockR);
// Apply Blake2 on columns of 64-bit words: (0,1,...,15) , then
// (16,17,..31)... finally (112,113,...127)
for (unsigned i = 0; i < 8; ++i) {
/* 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) {
BLAKE2_ROUND_NOMSG(
blockR.v[16 * i], blockR.v[16 * i + 1], blockR.v[16 * i + 2],
blockR.v[16 * i + 3], blockR.v[16 * i + 4], blockR.v[16 * i + 5],
@ -47,9 +48,9 @@ void fill_block(const block *prev_block, const block *ref_block,
blockR.v[16 * i + 15]);
}
// Apply Blake2 on rows of 64-bit words: (0,1,16,17,...112,113), then
// (2,3,18,19,...,114,115).. finally (14,15,30,31,...,126,127)
for (unsigned i = 0; i < 8; i++) {
/* Apply Blake2 on rows of 64-bit words: (0,1,16,17,...112,113), then
(2,3,18,19,...,114,115).. finally (14,15,30,31,...,126,127) */
for (i = 0; i < 8; i++) {
BLAKE2_ROUND_NOMSG(
blockR.v[2 * i], blockR.v[2 * i + 1], blockR.v[2 * i + 16],
blockR.v[2 * i + 17], blockR.v[2 * i + 32], blockR.v[2 * i + 33],
@ -63,10 +64,12 @@ void fill_block(const block *prev_block, const block *ref_block,
xor_block(next_block, &blockR);
}
void generate_addresses(const Argon2_instance_t *instance,
const Argon2_position_t *position,
void generate_addresses(const argon2_instance_t *instance,
const argon2_position_t *position,
uint64_t *pseudo_rands) {
block zero_block, input_block, address_block;
uint32_t i;
init_block_value(&zero_block, 0);
init_block_value(&input_block, 0);
init_block_value(&address_block, 0);
@ -79,7 +82,7 @@ void generate_addresses(const Argon2_instance_t *instance,
input_block.v[4] = instance->passes;
input_block.v[5] = instance->type;
for (uint32_t i = 0; i < instance->segment_length; ++i) {
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);
@ -91,18 +94,22 @@ void generate_addresses(const Argon2_instance_t *instance,
}
}
void fill_segment(const Argon2_instance_t *instance,
Argon2_position_t position) {
void fill_segment(const argon2_instance_t *instance,
argon2_position_t position) {
block *ref_block = NULL, *curr_block = NULL;
uint64_t pseudo_rand, ref_index, ref_lane;
uint32_t prev_offset, curr_offset;
uint32_t starting_index;
uint32_t i;
int data_independent_addressing = (instance->type == Argon2_i);
/* Pseudo-random values that determine the reference block position */
uint64_t *pseudo_rands = NULL;
if (instance == NULL) {
return;
}
uint64_t pseudo_rand, ref_index, ref_lane;
uint32_t prev_offset, curr_offset;
bool data_independent_addressing = (instance->type == Argon2_i);
// Pseudo-random values that determine the reference block position
uint64_t *pseudo_rands =
(uint64_t *)malloc(sizeof(uint64_t) * (instance->segment_length));
pseudo_rands = (uint64_t *)malloc(sizeof(uint64_t) * (instance->segment_length));
if (pseudo_rands == NULL) {
return;
@ -112,25 +119,25 @@ void fill_segment(const Argon2_instance_t *instance,
generate_addresses(instance, &position, pseudo_rands);
}
uint32_t starting_index = 0;
starting_index = 0;
if ((0 == position.pass) && (0 == position.slice)) {
starting_index = 2; // we have already generated the first two blocks
starting_index = 2; /* we have already generated the first two blocks */
}
// Offset of the current block
/* Offset of the current block */
curr_offset = position.lane * instance->lane_length +
position.slice * instance->segment_length + starting_index;
if (0 == curr_offset % instance->lane_length) {
// Last block in this lane
/* Last block in this lane */
prev_offset = curr_offset + instance->lane_length - 1;
} else {
// Previous block
/* Previous block */
prev_offset = curr_offset - 1;
}
for (uint32_t i = starting_index; i < instance->segment_length;
for (i = starting_index; i < instance->segment_length;
++i, ++curr_offset, ++prev_offset) {
/*1.1 Rotating prev_offset if needed */
if (curr_offset % instance->lane_length == 1) {
@ -149,7 +156,7 @@ void fill_segment(const Argon2_instance_t *instance,
ref_lane = ((pseudo_rand >> 32)) % instance->lanes;
if ((position.pass == 0) && (position.slice == 0)) {
// Can not reference other lanes yet
/* Can not reference other lanes yet */
ref_lane = position.lane;
}
@ -161,9 +168,8 @@ void fill_segment(const Argon2_instance_t *instance,
ref_lane == position.lane);
/* 2 Creating a new block */
block *ref_block =
instance->memory + instance->lane_length * ref_lane + ref_index;
block *curr_block = instance->memory + curr_offset;
ref_block = instance->memory + instance->lane_length * ref_lane + ref_index;
curr_block = instance->memory + curr_offset;
fill_block(instance->memory + prev_offset, ref_block, curr_block);
}

View File

@ -32,8 +32,8 @@ void fill_block(const block *prev_block, const block *ref_block,
* @param pseudo_rands Pointer to the array of 64-bit values
* @pre pseudo_rands must point to @a instance->segment_length allocated values
*/
void generate_addresses(const Argon2_instance_t *instance,
const Argon2_position_t *position,
void generate_addresses(const argon2_instance_t *instance,
const argon2_position_t *position,
uint64_t *pseudo_rands);
/*
@ -43,7 +43,7 @@ void generate_addresses(const Argon2_instance_t *instance,
* @param position Current position
* @pre all block pointers must be valid
*/
void fill_segment(const Argon2_instance_t *instance,
Argon2_position_t position);
void fill_segment(const argon2_instance_t *instance,
argon2_position_t position);
#endif /* ARGON2_REF_H */