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:
parent
d000ced1ac
commit
e0fa49a7a2
2
Makefile
2
Makefile
|
@ -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
|
||||
|
|
95
src/argon2.c
95
src/argon2.c
|
@ -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.";
|
||||
}
|
||||
|
|
120
src/argon2.h
120
src/argon2.h
|
@ -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
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
188
src/core.c
188
src/core.c
|
@ -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
|
||||
|
|
100
src/core.h
100
src/core.h
|
@ -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
|
||||
|
|
|
@ -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); \
|
||||
|
|
30
src/kat.c
30
src/kat.c
|
@ -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]);
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
158
src/main.c
158
src/main.c
|
@ -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")) {
|
||||
|
|
64
src/opt.c
64
src/opt.c
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
|
64
src/ref.c
64
src/ref.c
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
|
Loading…
Reference in New Issue