mirror of
https://github.com/jedisct1/libsodium.git
synced 2026-08-27 04:07:12 +09:00
Indent
This commit is contained in:
@@ -12,7 +12,7 @@
|
||||
*/
|
||||
|
||||
#ifdef HAVE_SYS_MMAN_H
|
||||
# include <sys/mman.h>
|
||||
#include <sys/mman.h>
|
||||
#endif
|
||||
#include <errno.h>
|
||||
#include <stdint.h>
|
||||
@@ -21,46 +21,56 @@
|
||||
#include <string.h>
|
||||
|
||||
#include "crypto_generichash_blake2b.h"
|
||||
#include "private/common.h"
|
||||
#include "runtime.h"
|
||||
#include "utils.h"
|
||||
#include "private/common.h"
|
||||
|
||||
#include "argon2-core.h"
|
||||
#include "blake2b-long.h"
|
||||
|
||||
#if !defined(MAP_ANON) && defined(MAP_ANONYMOUS)
|
||||
# define MAP_ANON MAP_ANONYMOUS
|
||||
#define MAP_ANON MAP_ANONYMOUS
|
||||
#endif
|
||||
|
||||
static fill_segment_fn fill_segment = fill_segment_ref;
|
||||
|
||||
/***************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));
|
||||
}
|
||||
|
||||
void copy_block(block *dst, const block *src) {
|
||||
void
|
||||
copy_block(block *dst, const block *src)
|
||||
{
|
||||
memcpy(dst->v, src->v, sizeof(uint64_t) * ARGON2_QWORDS_IN_BLOCK);
|
||||
}
|
||||
|
||||
void xor_block(block *dst, const block *src) {
|
||||
void
|
||||
xor_block(block *dst, const block *src)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < ARGON2_QWORDS_IN_BLOCK; ++i) {
|
||||
dst->v[i] ^= src->v[i];
|
||||
}
|
||||
}
|
||||
|
||||
static void load_block(block *dst, const void *input) {
|
||||
static void
|
||||
load_block(block *dst, const void *input)
|
||||
{
|
||||
unsigned i;
|
||||
for (i = 0; i < ARGON2_QWORDS_IN_BLOCK; ++i) {
|
||||
dst->v[i] = LOAD64_LE((const uint8_t *)input + i * sizeof(dst->v[i]));
|
||||
dst->v[i] = LOAD64_LE((const uint8_t *) input + i * sizeof(dst->v[i]));
|
||||
}
|
||||
}
|
||||
|
||||
static void store_block(void *output, const block *src) {
|
||||
static void
|
||||
store_block(void *output, const block *src)
|
||||
{
|
||||
unsigned i;
|
||||
for (i = 0; i < ARGON2_QWORDS_IN_BLOCK; ++i) {
|
||||
STORE64_LE((uint8_t *)output + i * sizeof(src->v[i]), src->v[i]);
|
||||
STORE64_LE((uint8_t *) output + i * sizeof(src->v[i]), src->v[i]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -72,8 +82,10 @@ static void store_block(void *output, const block *src) {
|
||||
*/
|
||||
static int allocate_memory(block_region **memory, uint32_t m_cost);
|
||||
|
||||
static int allocate_memory(block_region **region, uint32_t m_cost) {
|
||||
void *base;
|
||||
static int
|
||||
allocate_memory(block_region **region, uint32_t m_cost)
|
||||
{
|
||||
void * base;
|
||||
block *memory;
|
||||
size_t memory_size;
|
||||
|
||||
@@ -82,24 +94,26 @@ static int allocate_memory(block_region **region, uint32_t m_cost) {
|
||||
}
|
||||
memory_size = sizeof(block) * m_cost;
|
||||
if (m_cost == 0 ||
|
||||
memory_size / m_cost != sizeof(block)) { /*1. Check for multiplication overflow*/
|
||||
memory_size / m_cost !=
|
||||
sizeof(block)) { /*1. Check for multiplication overflow*/
|
||||
return ARGON2_MEMORY_ALLOCATION_ERROR; /* LCOV_EXCL_LINE */
|
||||
}
|
||||
*region = (block_region *)malloc(sizeof(block_region)); /*2. Try to allocate region*/
|
||||
*region = (block_region *) malloc(
|
||||
sizeof(block_region)); /*2. Try to allocate region*/
|
||||
if (!*region) {
|
||||
return ARGON2_MEMORY_ALLOCATION_ERROR; /* LCOV_EXCL_LINE */
|
||||
}
|
||||
|
||||
#if defined(MAP_ANON) && defined(HAVE_MMAP)
|
||||
if ((base = mmap(NULL, memory_size, PROT_READ | PROT_WRITE,
|
||||
# ifdef MAP_NOCORE
|
||||
#ifdef MAP_NOCORE
|
||||
MAP_ANON | MAP_PRIVATE | MAP_NOCORE,
|
||||
# else
|
||||
#else
|
||||
MAP_ANON | MAP_PRIVATE,
|
||||
# endif
|
||||
#endif
|
||||
-1, 0)) == MAP_FAILED) {
|
||||
base = NULL; /* LCOV_EXCL_LINE */
|
||||
} /* LCOV_EXCL_LINE */
|
||||
} /* LCOV_EXCL_LINE */
|
||||
memcpy(&memory, &base, sizeof memory);
|
||||
#elif defined(HAVE_POSIX_MEMALIGN)
|
||||
if ((errno = posix_memalign((void **) &base, 64, memory_size)) != 0) {
|
||||
@@ -109,7 +123,7 @@ static int allocate_memory(block_region **region, uint32_t m_cost) {
|
||||
#else
|
||||
memory = NULL;
|
||||
if (memory_size + 63 < memory_size) {
|
||||
base = NULL;
|
||||
base = NULL;
|
||||
errno = ENOMEM;
|
||||
} else if ((base = malloc(memory_size + 63)) != NULL) {
|
||||
uint8_t *aligned = ((uint8_t *) base) + 63;
|
||||
@@ -120,9 +134,9 @@ static int allocate_memory(block_region **region, uint32_t m_cost) {
|
||||
if (base == NULL) {
|
||||
return ARGON2_MEMORY_ALLOCATION_ERROR; /* LCOV_EXCL_LINE */
|
||||
}
|
||||
(*region)->base = base;
|
||||
(*region)->base = base;
|
||||
(*region)->memory = memory;
|
||||
(*region)->size = memory_size;
|
||||
(*region)->size = memory_size;
|
||||
|
||||
return ARGON2_OK;
|
||||
}
|
||||
@@ -135,7 +149,9 @@ static int allocate_memory(block_region **region, uint32_t m_cost) {
|
||||
*/
|
||||
static void clear_memory(argon2_instance_t *instance, int clear);
|
||||
|
||||
static void clear_memory(argon2_instance_t *instance, int clear) {
|
||||
static void
|
||||
clear_memory(argon2_instance_t *instance, int clear)
|
||||
{
|
||||
if (instance->region != NULL && clear) {
|
||||
/* LCOV_EXCL_START */
|
||||
sodium_memzero(instance->region->memory,
|
||||
@@ -149,7 +165,9 @@ static void clear_memory(argon2_instance_t *instance, int clear) {
|
||||
*/
|
||||
static void free_memory(block_region *memory);
|
||||
|
||||
static void free_memory(block_region *region) {
|
||||
static void
|
||||
free_memory(block_region *region)
|
||||
{
|
||||
if (region->base) {
|
||||
#if defined(MAP_ANON) && defined(HAVE_MMAP)
|
||||
if (munmap(region->base, region->size)) {
|
||||
@@ -162,18 +180,22 @@ static void free_memory(block_region *region) {
|
||||
free(region);
|
||||
}
|
||||
|
||||
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;
|
||||
block blockhash;
|
||||
uint32_t l;
|
||||
|
||||
copy_block(&blockhash, instance->region->memory + instance->lane_length - 1);
|
||||
copy_block(&blockhash,
|
||||
instance->region->memory + instance->lane_length - 1);
|
||||
|
||||
/* 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->region->memory + last_block_in_lane);
|
||||
xor_block(&blockhash,
|
||||
instance->region->memory + last_block_in_lane);
|
||||
}
|
||||
|
||||
/* Hash the result */
|
||||
@@ -196,9 +218,11 @@ 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,
|
||||
int 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
|
||||
@@ -266,8 +290,10 @@ uint32_t index_alpha(const argon2_instance_t *instance,
|
||||
return absolute_position;
|
||||
}
|
||||
|
||||
int fill_memory_blocks(argon2_instance_t *instance) {
|
||||
int result;
|
||||
int
|
||||
fill_memory_blocks(argon2_instance_t *instance)
|
||||
{
|
||||
int result;
|
||||
uint32_t r, s;
|
||||
|
||||
if (instance == NULL || instance->lanes == 0) {
|
||||
@@ -281,11 +307,11 @@ int fill_memory_blocks(argon2_instance_t *instance) {
|
||||
for (l = 0; l < instance->lanes; ++l) {
|
||||
argon2_position_t position;
|
||||
|
||||
position.pass = r;
|
||||
position.lane = l;
|
||||
position.slice = (uint8_t)s;
|
||||
position.pass = r;
|
||||
position.lane = l;
|
||||
position.slice = (uint8_t) s;
|
||||
position.index = 0;
|
||||
result = fill_segment(instance, position);
|
||||
result = fill_segment(instance, position);
|
||||
if (ARGON2_OK != result) {
|
||||
return result; /* LCOV_EXCL_LINE */
|
||||
}
|
||||
@@ -295,8 +321,10 @@ int fill_memory_blocks(argon2_instance_t *instance) {
|
||||
return ARGON2_OK;
|
||||
}
|
||||
|
||||
int validate_inputs(const argon2_context *context) {
|
||||
/* LCOV_EXCL_START */
|
||||
int
|
||||
validate_inputs(const argon2_context *context)
|
||||
{
|
||||
/* LCOV_EXCL_START */
|
||||
if (NULL == context) {
|
||||
return ARGON2_INCORRECT_PARAMETER;
|
||||
}
|
||||
@@ -418,13 +446,14 @@ int validate_inputs(const argon2_context *context) {
|
||||
return ARGON2_OK;
|
||||
}
|
||||
|
||||
void fill_first_blocks(uint8_t *blockhash, const argon2_instance_t *instance) {
|
||||
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) */
|
||||
uint8_t blockhash_bytes[ARGON2_BLOCK_SIZE];
|
||||
for (l = 0; l < instance->lanes; ++l) {
|
||||
|
||||
STORE32_LE(blockhash + ARGON2_PREHASH_DIGEST_LENGTH, 0);
|
||||
STORE32_LE(blockhash + ARGON2_PREHASH_DIGEST_LENGTH + 4, l);
|
||||
blake2b_long(blockhash_bytes, ARGON2_BLOCK_SIZE, blockhash,
|
||||
@@ -441,10 +470,11 @@ void fill_first_blocks(uint8_t *blockhash, const argon2_instance_t *instance) {
|
||||
sodium_memzero(blockhash_bytes, ARGON2_BLOCK_SIZE);
|
||||
}
|
||||
|
||||
void initial_hash(uint8_t *blockhash, argon2_context *context,
|
||||
argon2_type type) {
|
||||
void
|
||||
initial_hash(uint8_t *blockhash, argon2_context *context, argon2_type type)
|
||||
{
|
||||
crypto_generichash_blake2b_state BlakeHash;
|
||||
uint8_t value[4U /* sizeof(uint32_t) */];
|
||||
uint8_t value[4U /* sizeof(uint32_t) */];
|
||||
|
||||
if (NULL == context || NULL == blockhash) {
|
||||
return; /* LCOV_EXCL_LINE */
|
||||
@@ -468,19 +498,19 @@ void initial_hash(uint8_t *blockhash, argon2_context *context,
|
||||
STORE32_LE(value, ARGON2_VERSION_NUMBER);
|
||||
crypto_generichash_blake2b_update(&BlakeHash, value, sizeof(value));
|
||||
|
||||
STORE32_LE(value, (uint32_t)type);
|
||||
STORE32_LE(value, (uint32_t) type);
|
||||
crypto_generichash_blake2b_update(&BlakeHash, value, sizeof(value));
|
||||
|
||||
STORE32_LE(value, context->pwdlen);
|
||||
crypto_generichash_blake2b_update(&BlakeHash, value, sizeof(value));
|
||||
|
||||
if (context->pwd != NULL) {
|
||||
crypto_generichash_blake2b_update(&BlakeHash, (const uint8_t *)context->pwd,
|
||||
context->pwdlen);
|
||||
crypto_generichash_blake2b_update(
|
||||
&BlakeHash, (const uint8_t *) context->pwd, context->pwdlen);
|
||||
|
||||
if (context->flags & ARGON2_FLAG_CLEAR_PASSWORD) {
|
||||
sodium_memzero(context->pwd, context->pwdlen); /* LCOV_EXCL_LINE */
|
||||
context->pwdlen = 0; /* LCOV_EXCL_LINE */
|
||||
context->pwdlen = 0; /* LCOV_EXCL_LINE */
|
||||
}
|
||||
}
|
||||
|
||||
@@ -488,41 +518,44 @@ void initial_hash(uint8_t *blockhash, argon2_context *context,
|
||||
crypto_generichash_blake2b_update(&BlakeHash, value, sizeof(value));
|
||||
|
||||
if (context->salt != NULL) {
|
||||
crypto_generichash_blake2b_update(&BlakeHash, (const uint8_t *)context->salt,
|
||||
context->saltlen);
|
||||
crypto_generichash_blake2b_update(
|
||||
&BlakeHash, (const uint8_t *) context->salt, context->saltlen);
|
||||
}
|
||||
|
||||
STORE32_LE(value, context->secretlen);
|
||||
crypto_generichash_blake2b_update(&BlakeHash, value, sizeof(value));
|
||||
|
||||
if (context->secret != NULL) {
|
||||
/* LCOV_EXCL_START */
|
||||
crypto_generichash_blake2b_update(&BlakeHash, (const uint8_t *)context->secret,
|
||||
context->secretlen);
|
||||
/* LCOV_EXCL_START */
|
||||
crypto_generichash_blake2b_update(
|
||||
&BlakeHash, (const uint8_t *) context->secret, context->secretlen);
|
||||
|
||||
if (context->flags & ARGON2_FLAG_CLEAR_SECRET) {
|
||||
sodium_memzero(context->secret, context->secretlen);
|
||||
context->secretlen = 0;
|
||||
}
|
||||
/* LCOV_EXCL_STOP */
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
STORE32_LE(value, context->adlen);
|
||||
crypto_generichash_blake2b_update(&BlakeHash, value, sizeof(value));
|
||||
|
||||
if (context->ad != NULL) {
|
||||
/* LCOV_EXCL_START */
|
||||
crypto_generichash_blake2b_update(&BlakeHash, (const uint8_t *)context->ad,
|
||||
context->adlen);
|
||||
/* LCOV_EXCL_STOP */
|
||||
/* LCOV_EXCL_START */
|
||||
crypto_generichash_blake2b_update(
|
||||
&BlakeHash, (const uint8_t *) context->ad, context->adlen);
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
crypto_generichash_blake2b_final(&BlakeHash, blockhash, ARGON2_PREHASH_DIGEST_LENGTH);
|
||||
crypto_generichash_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;
|
||||
int result = ARGON2_OK;
|
||||
|
||||
if (instance == NULL || context == NULL)
|
||||
return ARGON2_INCORRECT_PARAMETER;
|
||||
@@ -552,11 +585,13 @@ int initialize(argon2_instance_t *instance, argon2_context *context) {
|
||||
return ARGON2_OK;
|
||||
}
|
||||
|
||||
int argon2_pick_best_implementation(void)
|
||||
int
|
||||
argon2_pick_best_implementation(void)
|
||||
{
|
||||
/* LCOV_EXCL_START */
|
||||
#if (defined(HAVE_EMMINTRIN_H) && defined(HAVE_TMMINTRIN_H)) || \
|
||||
(defined(_MSC_VER) && (defined(_M_X64) || defined(_M_AMD64) || defined(_M_IX86)))
|
||||
(defined(_MSC_VER) && \
|
||||
(defined(_M_X64) || defined(_M_AMD64) || defined(_M_IX86)))
|
||||
if (sodium_runtime_has_ssse3()) {
|
||||
fill_segment = fill_segment_ssse3;
|
||||
return 0;
|
||||
@@ -565,5 +600,5 @@ int argon2_pick_best_implementation(void)
|
||||
fill_segment = fill_segment_ref;
|
||||
|
||||
return 0;
|
||||
/* LCOV_EXCL_STOP */
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
@@ -24,7 +24,7 @@ enum argon2_ctx_constants {
|
||||
ARGON2_VERSION_NUMBER = 0x13,
|
||||
|
||||
/* Memory block size in bytes */
|
||||
ARGON2_BLOCK_SIZE = 1024,
|
||||
ARGON2_BLOCK_SIZE = 1024,
|
||||
ARGON2_QWORDS_IN_BLOCK = ARGON2_BLOCK_SIZE / 8,
|
||||
ARGON2_OWORDS_IN_BLOCK = ARGON2_BLOCK_SIZE / 16,
|
||||
|
||||
@@ -35,7 +35,7 @@ enum argon2_ctx_constants {
|
||||
|
||||
/* Pre-hashing digest length and its extension*/
|
||||
ARGON2_PREHASH_DIGEST_LENGTH = 64,
|
||||
ARGON2_PREHASH_SEED_LENGTH = 72
|
||||
ARGON2_PREHASH_SEED_LENGTH = 72
|
||||
};
|
||||
|
||||
/*************************Argon2 internal data
|
||||
@@ -46,10 +46,12 @@ enum argon2_ctx_constants {
|
||||
* Memory blocks can be copied, XORed. Internal words can be accessed by [] (no
|
||||
* bounds checking).
|
||||
*/
|
||||
typedef struct block_ { uint64_t v[ARGON2_QWORDS_IN_BLOCK]; } block;
|
||||
typedef struct block_ {
|
||||
uint64_t v[ARGON2_QWORDS_IN_BLOCK];
|
||||
} block;
|
||||
|
||||
typedef struct block_region_ {
|
||||
void *base;
|
||||
void * base;
|
||||
block *memory;
|
||||
size_t size;
|
||||
} block_region;
|
||||
@@ -72,15 +74,15 @@ void xor_block(block *dst, const block *src);
|
||||
* thread
|
||||
*/
|
||||
typedef struct Argon2_instance_t {
|
||||
block_region *region; /* Memory region 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 */
|
||||
block_region *region; /* Memory region 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;
|
||||
|
||||
/*
|
||||
@@ -90,14 +92,14 @@ typedef struct Argon2_instance_t {
|
||||
typedef struct Argon2_position_t {
|
||||
uint32_t pass;
|
||||
uint32_t lane;
|
||||
uint8_t slice;
|
||||
uint8_t slice;
|
||||
uint32_t index;
|
||||
} 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_position_t pos;
|
||||
} argon2_thread_data;
|
||||
|
||||
/*************************Argon2 core
|
||||
@@ -180,12 +182,12 @@ void finalize(const argon2_context *context, argon2_instance_t *instance);
|
||||
* @pre all block pointers must be valid
|
||||
*/
|
||||
typedef int (*fill_segment_fn)(const argon2_instance_t *instance,
|
||||
argon2_position_t position);
|
||||
argon2_position_t position);
|
||||
int argon2_pick_best_implementation(void);
|
||||
int fill_segment_ssse3(const argon2_instance_t *instance,
|
||||
argon2_position_t position);
|
||||
argon2_position_t position);
|
||||
int fill_segment_ref(const argon2_instance_t *instance,
|
||||
argon2_position_t position);
|
||||
argon2_position_t position);
|
||||
|
||||
/*
|
||||
* Function that fills the entire memory t_cost times based on the first two
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
#include "argon2-encoding.h"
|
||||
#include "argon2-core.h"
|
||||
#include <limits.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <limits.h>
|
||||
#include "argon2-core.h"
|
||||
#include "argon2-encoding.h"
|
||||
|
||||
/*
|
||||
* Example code for a decoder and encoder of "hash strings", with Argon2
|
||||
@@ -54,8 +54,9 @@
|
||||
* Some macros for constant-time comparisons. These work over values in
|
||||
* the 0..255 range. Returned value is 0x00 on "false", 0xFF on "true".
|
||||
*/
|
||||
#define EQ(x, y) ((((0U - ((unsigned)(x) ^ (unsigned)(y))) >> 8) & 0xFF) ^ 0xFF)
|
||||
#define GT(x, y) ((((unsigned)(y) - (unsigned)(x)) >> 8) & 0xFF)
|
||||
#define EQ(x, y) \
|
||||
((((0U - ((unsigned) (x) ^ (unsigned) (y))) >> 8) & 0xFF) ^ 0xFF)
|
||||
#define GT(x, y) ((((unsigned) (y) - (unsigned) (x)) >> 8) & 0xFF)
|
||||
#define GE(x, y) (GT(y, x) ^ 0xFF)
|
||||
#define LT(x, y) GT(y, x)
|
||||
#define LE(x, y) GE(y, x)
|
||||
@@ -63,7 +64,9 @@
|
||||
/*
|
||||
* Convert value x (0..63) to corresponding Base64 character.
|
||||
*/
|
||||
static int b64_byte_to_char(unsigned x) {
|
||||
static int
|
||||
b64_byte_to_char(unsigned x)
|
||||
{
|
||||
return (LT(x, 26) & (x + 'A')) |
|
||||
(GE(x, 26) & LT(x, 52) & (x + ('a' - 26))) |
|
||||
(GE(x, 52) & LT(x, 62) & (x + ('0' - 52))) | (EQ(x, 62) & '+') |
|
||||
@@ -74,7 +77,9 @@ static int b64_byte_to_char(unsigned x) {
|
||||
* Convert character c to the corresponding 6-bit value. If character c
|
||||
* is not a Base64 character, then 0xFF (255) is returned.
|
||||
*/
|
||||
static unsigned b64_char_to_byte(int c) {
|
||||
static unsigned
|
||||
b64_char_to_byte(int c)
|
||||
{
|
||||
unsigned x;
|
||||
|
||||
x = (GE(c, 'A') & LE(c, 'Z') & (c - 'A')) |
|
||||
@@ -92,11 +97,12 @@ static unsigned b64_char_to_byte(int c) {
|
||||
* in the buffer, and the output length (counted WITHOUT the terminating
|
||||
* zero) is returned.
|
||||
*/
|
||||
static size_t to_base64(char *dst, size_t dst_len, const void *src,
|
||||
size_t src_len) {
|
||||
size_t olen;
|
||||
static size_t
|
||||
to_base64(char *dst, size_t dst_len, const void *src, size_t src_len)
|
||||
{
|
||||
size_t olen;
|
||||
const unsigned char *buf;
|
||||
unsigned acc, acc_len;
|
||||
unsigned acc, acc_len;
|
||||
|
||||
olen = (src_len / 3) << 2;
|
||||
switch (src_len % 3) {
|
||||
@@ -108,21 +114,21 @@ static size_t to_base64(char *dst, size_t dst_len, const void *src,
|
||||
break;
|
||||
}
|
||||
if (dst_len <= olen) {
|
||||
return (size_t)-1;
|
||||
return (size_t) -1;
|
||||
}
|
||||
acc = 0;
|
||||
acc = 0;
|
||||
acc_len = 0;
|
||||
buf = (const unsigned char *)src;
|
||||
buf = (const unsigned char *) src;
|
||||
while (src_len-- > 0) {
|
||||
acc = (acc << 8) + (*buf++);
|
||||
acc_len += 8;
|
||||
while (acc_len >= 6) {
|
||||
acc_len -= 6;
|
||||
*dst++ = (char)b64_byte_to_char((acc >> acc_len) & 0x3F);
|
||||
*dst++ = (char) b64_byte_to_char((acc >> acc_len) & 0x3F);
|
||||
}
|
||||
}
|
||||
if (acc_len > 0) {
|
||||
*dst++ = (char)b64_byte_to_char((acc << (6 - acc_len)) & 0x3F);
|
||||
*dst++ = (char) b64_byte_to_char((acc << (6 - acc_len)) & 0x3F);
|
||||
}
|
||||
*dst++ = 0;
|
||||
return olen;
|
||||
@@ -141,14 +147,16 @@ static size_t to_base64(char *dst, size_t dst_len, const void *src,
|
||||
* points to the first non-Base64 character in the source stream, which
|
||||
* may be the terminating zero.
|
||||
*/
|
||||
static const char *from_base64(void *dst, size_t *dst_len, const char *src) {
|
||||
size_t len;
|
||||
static const char *
|
||||
from_base64(void *dst, size_t *dst_len, const char *src)
|
||||
{
|
||||
size_t len;
|
||||
unsigned char *buf;
|
||||
unsigned acc, acc_len;
|
||||
unsigned acc, acc_len;
|
||||
|
||||
buf = (unsigned char *)dst;
|
||||
len = 0;
|
||||
acc = 0;
|
||||
buf = (unsigned char *) dst;
|
||||
len = 0;
|
||||
acc = 0;
|
||||
acc_len = 0;
|
||||
for (;;) {
|
||||
unsigned d;
|
||||
@@ -189,8 +197,10 @@ static const char *from_base64(void *dst, size_t *dst_len, const char *src) {
|
||||
* minimal (extra leading zeros), or the value does not fit in an
|
||||
* 'unsigned long', then NULL is returned.
|
||||
*/
|
||||
static const char *decode_decimal(const char *str, unsigned long *v) {
|
||||
const char *orig;
|
||||
static const char *
|
||||
decode_decimal(const char *str, unsigned long *v)
|
||||
{
|
||||
const char * orig;
|
||||
unsigned long acc;
|
||||
|
||||
acc = 0;
|
||||
@@ -206,10 +216,10 @@ static const char *decode_decimal(const char *str, unsigned long *v) {
|
||||
return NULL;
|
||||
}
|
||||
acc *= 10;
|
||||
if ((unsigned long)c > (ULONG_MAX - acc)) {
|
||||
if ((unsigned long) c > (ULONG_MAX - acc)) {
|
||||
return NULL;
|
||||
}
|
||||
acc += (unsigned long)c;
|
||||
acc += (unsigned long) c;
|
||||
}
|
||||
if (str == orig || (*orig == '0' && str != (orig + 1))) {
|
||||
return NULL;
|
||||
@@ -242,57 +252,61 @@ static const char *decode_decimal(const char *str, unsigned long *v) {
|
||||
* Decode an Argon2i hash string into the provided structure 'ctx'.
|
||||
* Returned value is ARGON2_OK on success.
|
||||
*/
|
||||
int decode_string(argon2_context *ctx, const char *str, argon2_type type) {
|
||||
/* Prefix checking */
|
||||
#define CC(prefix) \
|
||||
do { \
|
||||
size_t cc_len = strlen(prefix); \
|
||||
if (strncmp(str, prefix, cc_len) != 0) { \
|
||||
return ARGON2_DECODING_FAIL; \
|
||||
} \
|
||||
str += cc_len; \
|
||||
} while ((void)0, 0)
|
||||
int
|
||||
decode_string(argon2_context *ctx, const char *str, argon2_type type)
|
||||
{
|
||||
/* Prefix checking */
|
||||
#define CC(prefix) \
|
||||
do { \
|
||||
size_t cc_len = strlen(prefix); \
|
||||
if (strncmp(str, prefix, cc_len) != 0) { \
|
||||
return ARGON2_DECODING_FAIL; \
|
||||
} \
|
||||
str += cc_len; \
|
||||
} while ((void) 0, 0)
|
||||
|
||||
/* Optional prefix checking with supplied code */
|
||||
#define CC_opt(prefix, code) \
|
||||
do { \
|
||||
size_t cc_len = strlen(prefix); \
|
||||
if (strncmp(str, prefix, cc_len) == 0) { \
|
||||
str += cc_len; \
|
||||
{ code; } \
|
||||
} \
|
||||
} while ((void)0, 0)
|
||||
/* Optional prefix checking with supplied code */
|
||||
#define CC_opt(prefix, code) \
|
||||
do { \
|
||||
size_t cc_len = strlen(prefix); \
|
||||
if (strncmp(str, prefix, cc_len) == 0) { \
|
||||
str += cc_len; \
|
||||
{ \
|
||||
code; \
|
||||
} \
|
||||
} \
|
||||
} while ((void) 0, 0)
|
||||
|
||||
/* Decoding prefix into decimal */
|
||||
#define DECIMAL(x) \
|
||||
do { \
|
||||
unsigned long dec_x; \
|
||||
str = decode_decimal(str, &dec_x); \
|
||||
if (str == NULL) { \
|
||||
return ARGON2_DECODING_FAIL; \
|
||||
} \
|
||||
(x) = dec_x; \
|
||||
} while ((void)0, 0)
|
||||
/* Decoding prefix into decimal */
|
||||
#define DECIMAL(x) \
|
||||
do { \
|
||||
unsigned long dec_x; \
|
||||
str = decode_decimal(str, &dec_x); \
|
||||
if (str == NULL) { \
|
||||
return ARGON2_DECODING_FAIL; \
|
||||
} \
|
||||
(x) = dec_x; \
|
||||
} while ((void) 0, 0)
|
||||
|
||||
/* Decoding base64 into a binary buffer */
|
||||
#define BIN(buf, max_len, len) \
|
||||
do { \
|
||||
size_t bin_len = (max_len); \
|
||||
str = from_base64(buf, &bin_len, str); \
|
||||
if (str == NULL || bin_len > UINT32_MAX) { \
|
||||
return ARGON2_DECODING_FAIL; \
|
||||
} \
|
||||
(len) = (uint32_t)bin_len; \
|
||||
} while ((void)0, 0)
|
||||
/* Decoding base64 into a binary buffer */
|
||||
#define BIN(buf, max_len, len) \
|
||||
do { \
|
||||
size_t bin_len = (max_len); \
|
||||
str = from_base64(buf, &bin_len, str); \
|
||||
if (str == NULL || bin_len > UINT32_MAX) { \
|
||||
return ARGON2_DECODING_FAIL; \
|
||||
} \
|
||||
(len) = (uint32_t) bin_len; \
|
||||
} while ((void) 0, 0)
|
||||
|
||||
size_t maxsaltlen = ctx->saltlen;
|
||||
size_t maxoutlen = ctx->outlen;
|
||||
size_t maxsaltlen = ctx->saltlen;
|
||||
size_t maxoutlen = ctx->outlen;
|
||||
unsigned long val;
|
||||
unsigned long version = 0;
|
||||
int validation_result;
|
||||
int validation_result;
|
||||
|
||||
ctx->saltlen = 0;
|
||||
ctx->outlen = 0;
|
||||
ctx->outlen = 0;
|
||||
|
||||
if (type == Argon2_i) {
|
||||
CC("$argon2i");
|
||||
@@ -321,7 +335,7 @@ int decode_string(argon2_context *ctx, const char *str, argon2_type type) {
|
||||
if (val > UINT32_MAX) {
|
||||
return ARGON2_INCORRECT_TYPE;
|
||||
}
|
||||
ctx->lanes = (uint32_t) val;
|
||||
ctx->lanes = (uint32_t) val;
|
||||
ctx->threads = ctx->lanes;
|
||||
|
||||
CC("$");
|
||||
@@ -345,7 +359,9 @@ int decode_string(argon2_context *ctx, const char *str, argon2_type type) {
|
||||
|
||||
#define U32_STR_MAXSIZE 11U
|
||||
|
||||
static void u32_to_string(char *str, uint32_t x) {
|
||||
static void
|
||||
u32_to_string(char *str, uint32_t x)
|
||||
{
|
||||
char tmp[U32_STR_MAXSIZE - 1U];
|
||||
size_t i;
|
||||
|
||||
@@ -370,35 +386,36 @@ static void u32_to_string(char *str, uint32_t x) {
|
||||
*
|
||||
* On success, ARGON2_OK is returned.
|
||||
*/
|
||||
int encode_string(char *dst, size_t dst_len, argon2_context *ctx,
|
||||
argon2_type type) {
|
||||
#define SS(str) \
|
||||
do { \
|
||||
size_t pp_len = strlen(str); \
|
||||
if (pp_len >= dst_len) { \
|
||||
return ARGON2_ENCODING_FAIL; \
|
||||
} \
|
||||
memcpy(dst, str, pp_len + 1); \
|
||||
dst += pp_len; \
|
||||
dst_len -= pp_len; \
|
||||
} while ((void)0, 0)
|
||||
int
|
||||
encode_string(char *dst, size_t dst_len, argon2_context *ctx, argon2_type type)
|
||||
{
|
||||
#define SS(str) \
|
||||
do { \
|
||||
size_t pp_len = strlen(str); \
|
||||
if (pp_len >= dst_len) { \
|
||||
return ARGON2_ENCODING_FAIL; \
|
||||
} \
|
||||
memcpy(dst, str, pp_len + 1); \
|
||||
dst += pp_len; \
|
||||
dst_len -= pp_len; \
|
||||
} while ((void) 0, 0)
|
||||
|
||||
#define SX(x) \
|
||||
do { \
|
||||
char tmp[U32_STR_MAXSIZE]; \
|
||||
u32_to_string(tmp, x); \
|
||||
SS(tmp); \
|
||||
} while ((void)0, 0)
|
||||
#define SX(x) \
|
||||
do { \
|
||||
char tmp[U32_STR_MAXSIZE]; \
|
||||
u32_to_string(tmp, x); \
|
||||
SS(tmp); \
|
||||
} while ((void) 0, 0)
|
||||
|
||||
#define SB(buf, len) \
|
||||
do { \
|
||||
size_t sb_len = to_base64(dst, dst_len, buf, len); \
|
||||
if (sb_len == (size_t)-1) { \
|
||||
return ARGON2_ENCODING_FAIL; \
|
||||
} \
|
||||
dst += sb_len; \
|
||||
dst_len -= sb_len; \
|
||||
} while ((void)0, 0)
|
||||
#define SB(buf, len) \
|
||||
do { \
|
||||
size_t sb_len = to_base64(dst, dst_len, buf, len); \
|
||||
if (sb_len == (size_t) -1) { \
|
||||
return ARGON2_ENCODING_FAIL; \
|
||||
} \
|
||||
dst += sb_len; \
|
||||
dst_len -= sb_len; \
|
||||
} while ((void) 0, 0)
|
||||
|
||||
int validation_result;
|
||||
|
||||
|
||||
@@ -22,7 +22,8 @@ int encode_string(char *dst, size_t dst_len, argon2_context *ctx,
|
||||
|
||||
/*
|
||||
* Decodes an Argon2 hash string into the provided structure 'ctx'.
|
||||
* The fields ctx.saltlen, ctx.adlen, ctx.outlen set the maximal salt, ad, out length values
|
||||
* The fields ctx.saltlen, ctx.adlen, ctx.outlen set the maximal salt, ad, out
|
||||
* length values
|
||||
* that are allowed; invalid input string causes an error
|
||||
*
|
||||
* Returned value is ARGON2_OK on success.
|
||||
|
||||
@@ -15,14 +15,15 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "argon2.h"
|
||||
#include "argon2-core.h"
|
||||
#include "argon2.h"
|
||||
#include "blamka-round-ref.h"
|
||||
#include "private/common.h"
|
||||
|
||||
static void fill_block(const block *prev_block, const block *ref_block,
|
||||
block *next_block) {
|
||||
block blockR, block_tmp;
|
||||
static void
|
||||
fill_block(const block *prev_block, const block *ref_block, block *next_block)
|
||||
{
|
||||
block blockR, block_tmp;
|
||||
unsigned i;
|
||||
|
||||
copy_block(&blockR, ref_block);
|
||||
@@ -57,16 +58,20 @@ static void fill_block(const block *prev_block, const block *ref_block,
|
||||
xor_block(next_block, &blockR);
|
||||
}
|
||||
|
||||
static void fill_block_with_xor(const block *prev_block, const block *ref_block,
|
||||
block *next_block) {
|
||||
block blockR, block_tmp;
|
||||
static void
|
||||
fill_block_with_xor(const block *prev_block, const block *ref_block,
|
||||
block *next_block)
|
||||
{
|
||||
block blockR, block_tmp;
|
||||
unsigned i;
|
||||
|
||||
copy_block(&blockR, ref_block);
|
||||
xor_block(&blockR, prev_block);
|
||||
copy_block(&block_tmp, &blockR);
|
||||
xor_block(&block_tmp, next_block); /* Saving the next block contents for XOR over */
|
||||
/* Now blockR = ref_block + prev_block and bloc_tmp = ref_block + prev_block + next_block */
|
||||
xor_block(&block_tmp,
|
||||
next_block); /* Saving the next block contents for XOR over */
|
||||
/* Now blockR = ref_block + prev_block and bloc_tmp = ref_block + prev_block
|
||||
* + next_block */
|
||||
/* Apply Blake2 on columns of 64-bit words: (0,1,...,15) , then
|
||||
(16,17,..31)... finally (112,113,...127) */
|
||||
for (i = 0; i < 8; ++i) {
|
||||
@@ -103,10 +108,11 @@ static void fill_block_with_xor(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
|
||||
*/
|
||||
static void generate_addresses(const argon2_instance_t *instance,
|
||||
const argon2_position_t *position,
|
||||
uint64_t *pseudo_rands) {
|
||||
block zero_block, input_block, address_block, tmp_block;
|
||||
static void
|
||||
generate_addresses(const argon2_instance_t *instance,
|
||||
const argon2_position_t *position, uint64_t *pseudo_rands)
|
||||
{
|
||||
block zero_block, input_block, address_block, tmp_block;
|
||||
uint32_t i;
|
||||
|
||||
init_block_value(&zero_block, 0);
|
||||
@@ -134,13 +140,14 @@ static void generate_addresses(const argon2_instance_t *instance,
|
||||
}
|
||||
}
|
||||
|
||||
int fill_segment_ref(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
|
||||
fill_segment_ref(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;
|
||||
const int data_independent_addressing = 1; /* instance->type == Argon2_i */
|
||||
/* Pseudo-random values that determine the reference block position */
|
||||
uint64_t *pseudo_rands = NULL;
|
||||
@@ -150,7 +157,7 @@ int fill_segment_ref(const argon2_instance_t *instance,
|
||||
}
|
||||
|
||||
pseudo_rands =
|
||||
(uint64_t *)malloc(sizeof(uint64_t) * (instance->segment_length));
|
||||
(uint64_t *) malloc(sizeof(uint64_t) * (instance->segment_length));
|
||||
|
||||
if (pseudo_rands == NULL) {
|
||||
return ARGON2_MEMORY_ALLOCATION_ERROR;
|
||||
@@ -189,7 +196,7 @@ int fill_segment_ref(const argon2_instance_t *instance,
|
||||
/* 1.2.1 Taking pseudo-random value from the previous block */
|
||||
if (data_independent_addressing) {
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable: 6385)
|
||||
#pragma warning(disable : 6385)
|
||||
pseudo_rand = pseudo_rands[i];
|
||||
#pragma warning(pop)
|
||||
} else {
|
||||
@@ -212,13 +219,15 @@ int fill_segment_ref(const argon2_instance_t *instance,
|
||||
ref_lane == position.lane);
|
||||
|
||||
/* 2 Creating a new block */
|
||||
ref_block =
|
||||
instance->region->memory + instance->lane_length * ref_lane + ref_index;
|
||||
ref_block = instance->region->memory +
|
||||
instance->lane_length * ref_lane + ref_index;
|
||||
curr_block = instance->region->memory + curr_offset;
|
||||
if (position.pass != 0) {
|
||||
fill_block_with_xor(instance->region->memory + prev_offset, ref_block, curr_block);
|
||||
fill_block_with_xor(instance->region->memory + prev_offset,
|
||||
ref_block, curr_block);
|
||||
} else {
|
||||
fill_block(instance->region->memory + prev_offset, ref_block, curr_block);
|
||||
fill_block(instance->region->memory + prev_offset, ref_block,
|
||||
curr_block);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -226,4 +235,3 @@ int fill_segment_ref(const argon2_instance_t *instance,
|
||||
|
||||
return ARGON2_OK;
|
||||
}
|
||||
|
||||
|
||||
@@ -16,56 +16,32 @@
|
||||
#include <string.h>
|
||||
|
||||
#if (defined(HAVE_EMMINTRIN_H) && defined(HAVE_TMMINTRIN_H)) || \
|
||||
(defined(_MSC_VER) && (defined(_M_X64) || defined(_M_AMD64) || defined(_M_IX86)))
|
||||
(defined(_MSC_VER) && \
|
||||
(defined(_M_X64) || defined(_M_AMD64) || defined(_M_IX86)))
|
||||
|
||||
#pragma GCC target("sse2")
|
||||
#pragma GCC target("ssse3")
|
||||
|
||||
#ifdef _MSC_VER
|
||||
# include <intrin.h> /* for _mm_set_epi64x */
|
||||
#include <intrin.h> /* for _mm_set_epi64x */
|
||||
#endif
|
||||
#include <emmintrin.h>
|
||||
#include <tmmintrin.h>
|
||||
|
||||
#include "argon2.h"
|
||||
#include "argon2-core.h"
|
||||
#include "argon2.h"
|
||||
#include "blamka-round-ssse3.h"
|
||||
#include "private/common.h"
|
||||
|
||||
static void fill_block(__m128i *state, const uint8_t *ref_block, uint8_t *next_block) {
|
||||
__m128i block_XY[ARGON2_OWORDS_IN_BLOCK];
|
||||
static void
|
||||
fill_block(__m128i *state, const uint8_t *ref_block, uint8_t *next_block)
|
||||
{
|
||||
__m128i block_XY[ARGON2_OWORDS_IN_BLOCK];
|
||||
uint32_t i;
|
||||
|
||||
for (i = 0; i < ARGON2_OWORDS_IN_BLOCK; i++) {
|
||||
block_XY[i] = state[i] = _mm_xor_si128(
|
||||
state[i], _mm_loadu_si128((__m128i const *)(&ref_block[16 * i])));
|
||||
}
|
||||
|
||||
for (i = 0; i < 8; ++i) {
|
||||
BLAKE2_ROUND(state[8 * i + 0], state[8 * i + 1], state[8 * i + 2],
|
||||
state[8 * i + 3], state[8 * i + 4], state[8 * i + 5],
|
||||
state[8 * i + 6], state[8 * i + 7]);
|
||||
}
|
||||
|
||||
for (i = 0; i < 8; ++i) {
|
||||
BLAKE2_ROUND(state[8 * 0 + i], state[8 * 1 + i], state[8 * 2 + i],
|
||||
state[8 * 3 + i], state[8 * 4 + i], state[8 * 5 + i],
|
||||
state[8 * 6 + i], state[8 * 7 + i]);
|
||||
}
|
||||
|
||||
for (i = 0; i < ARGON2_OWORDS_IN_BLOCK; i++) {
|
||||
state[i] = _mm_xor_si128(state[i], block_XY[i]);
|
||||
_mm_storeu_si128((__m128i *)(&next_block[16 * i]), state[i]);
|
||||
}
|
||||
}
|
||||
|
||||
static void fill_block_with_xor(__m128i *state, const uint8_t *ref_block, uint8_t *next_block) {
|
||||
__m128i block_XY[ARGON2_OWORDS_IN_BLOCK];
|
||||
uint32_t i;
|
||||
|
||||
for (i = 0; i < ARGON2_OWORDS_IN_BLOCK; i++) {
|
||||
state[i] = _mm_xor_si128(state[i], _mm_loadu_si128((__m128i const *)(&ref_block[16 * i])));
|
||||
block_XY[i] = _mm_xor_si128(state[i], _mm_loadu_si128((__m128i const *)(&next_block[16 * i])));
|
||||
state[i], _mm_loadu_si128((__m128i const *) (&ref_block[16 * i])));
|
||||
}
|
||||
|
||||
for (i = 0; i < 8; ++i) {
|
||||
@@ -82,14 +58,47 @@ static void fill_block_with_xor(__m128i *state, const uint8_t *ref_block, uint8_
|
||||
|
||||
for (i = 0; i < ARGON2_OWORDS_IN_BLOCK; i++) {
|
||||
state[i] = _mm_xor_si128(state[i], block_XY[i]);
|
||||
_mm_storeu_si128((__m128i *)(&next_block[16 * i]), state[i]);
|
||||
_mm_storeu_si128((__m128i *) (&next_block[16 * i]), state[i]);
|
||||
}
|
||||
}
|
||||
|
||||
static void generate_addresses(const argon2_instance_t *instance,
|
||||
const argon2_position_t *position,
|
||||
uint64_t *pseudo_rands) {
|
||||
block address_block, input_block, tmp_block;
|
||||
static void
|
||||
fill_block_with_xor(__m128i *state, const uint8_t *ref_block,
|
||||
uint8_t *next_block)
|
||||
{
|
||||
__m128i block_XY[ARGON2_OWORDS_IN_BLOCK];
|
||||
uint32_t i;
|
||||
|
||||
for (i = 0; i < ARGON2_OWORDS_IN_BLOCK; i++) {
|
||||
state[i] = _mm_xor_si128(
|
||||
state[i], _mm_loadu_si128((__m128i const *) (&ref_block[16 * i])));
|
||||
block_XY[i] = _mm_xor_si128(
|
||||
state[i], _mm_loadu_si128((__m128i const *) (&next_block[16 * i])));
|
||||
}
|
||||
|
||||
for (i = 0; i < 8; ++i) {
|
||||
BLAKE2_ROUND(state[8 * i + 0], state[8 * i + 1], state[8 * i + 2],
|
||||
state[8 * i + 3], state[8 * i + 4], state[8 * i + 5],
|
||||
state[8 * i + 6], state[8 * i + 7]);
|
||||
}
|
||||
|
||||
for (i = 0; i < 8; ++i) {
|
||||
BLAKE2_ROUND(state[8 * 0 + i], state[8 * 1 + i], state[8 * 2 + i],
|
||||
state[8 * 3 + i], state[8 * 4 + i], state[8 * 5 + i],
|
||||
state[8 * 6 + i], state[8 * 7 + i]);
|
||||
}
|
||||
|
||||
for (i = 0; i < ARGON2_OWORDS_IN_BLOCK; i++) {
|
||||
state[i] = _mm_xor_si128(state[i], block_XY[i]);
|
||||
_mm_storeu_si128((__m128i *) (&next_block[16 * i]), state[i]);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
generate_addresses(const argon2_instance_t *instance,
|
||||
const argon2_position_t *position, uint64_t *pseudo_rands)
|
||||
{
|
||||
block address_block, input_block, tmp_block;
|
||||
uint32_t i;
|
||||
|
||||
init_block_value(&address_block, 0);
|
||||
@@ -115,9 +124,11 @@ static void generate_addresses(const argon2_instance_t *instance,
|
||||
/* Increasing index counter */
|
||||
input_block.v[6]++;
|
||||
/* First iteration of G */
|
||||
fill_block_with_xor(zero_block, (uint8_t *)&input_block.v, (uint8_t *)&tmp_block.v);
|
||||
fill_block_with_xor(zero_block, (uint8_t *) &input_block.v,
|
||||
(uint8_t *) &tmp_block.v);
|
||||
/* Second iteration of G */
|
||||
fill_block_with_xor(zero2_block, (uint8_t *)&tmp_block.v, (uint8_t *)&address_block.v);
|
||||
fill_block_with_xor(zero2_block, (uint8_t *) &tmp_block.v,
|
||||
(uint8_t *) &address_block.v);
|
||||
}
|
||||
|
||||
pseudo_rands[i] = address_block.v[i % ARGON2_ADDRESSES_IN_BLOCK];
|
||||
@@ -125,13 +136,15 @@ static void generate_addresses(const argon2_instance_t *instance,
|
||||
}
|
||||
}
|
||||
|
||||
int fill_segment_ssse3(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];
|
||||
int
|
||||
fill_segment_ssse3(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];
|
||||
const int data_independent_addressing = 1; /* instance->type == Argon2_i */
|
||||
|
||||
/* Pseudo-random values that determine the reference block position */
|
||||
@@ -142,7 +155,7 @@ int fill_segment_ssse3(const argon2_instance_t *instance,
|
||||
}
|
||||
|
||||
pseudo_rands =
|
||||
(uint64_t *)malloc(sizeof(uint64_t) * instance->segment_length);
|
||||
(uint64_t *) malloc(sizeof(uint64_t) * instance->segment_length);
|
||||
if (pseudo_rands == NULL) {
|
||||
return ARGON2_MEMORY_ALLOCATION_ERROR;
|
||||
}
|
||||
@@ -169,7 +182,8 @@ int fill_segment_ssse3(const argon2_instance_t *instance,
|
||||
prev_offset = curr_offset - 1;
|
||||
}
|
||||
|
||||
memcpy(state, ((instance->region->memory + prev_offset)->v), ARGON2_BLOCK_SIZE);
|
||||
memcpy(state, ((instance->region->memory + prev_offset)->v),
|
||||
ARGON2_BLOCK_SIZE);
|
||||
|
||||
for (i = starting_index; i < instance->segment_length;
|
||||
++i, ++curr_offset, ++prev_offset) {
|
||||
@@ -182,7 +196,7 @@ int fill_segment_ssse3(const argon2_instance_t *instance,
|
||||
/* 1.2.1 Taking pseudo-random value from the previous block */
|
||||
if (data_independent_addressing) {
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable: 6385)
|
||||
#pragma warning(disable : 6385)
|
||||
pseudo_rand = pseudo_rands[i];
|
||||
#pragma warning(pop)
|
||||
} else {
|
||||
@@ -205,13 +219,15 @@ int fill_segment_ssse3(const argon2_instance_t *instance,
|
||||
ref_lane == position.lane);
|
||||
|
||||
/* 2 Creating a new block */
|
||||
ref_block =
|
||||
instance->region->memory + instance->lane_length * ref_lane + ref_index;
|
||||
ref_block = instance->region->memory +
|
||||
instance->lane_length * ref_lane + ref_index;
|
||||
curr_block = instance->region->memory + curr_offset;
|
||||
if (position.pass != 0) {
|
||||
fill_block_with_xor(state, (uint8_t *)ref_block->v, (uint8_t *)curr_block->v);
|
||||
fill_block_with_xor(state, (uint8_t *) ref_block->v,
|
||||
(uint8_t *) curr_block->v);
|
||||
} else {
|
||||
fill_block(state, (uint8_t *)ref_block->v, (uint8_t *)curr_block->v);
|
||||
fill_block(state, (uint8_t *) ref_block->v,
|
||||
(uint8_t *) curr_block->v);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -11,22 +11,24 @@
|
||||
* <http://creativecommons.org/publicdomain/zero/1.0/>.
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <limits.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "utils.h"
|
||||
|
||||
#include "argon2.h"
|
||||
#include "argon2-encoding.h"
|
||||
#include "argon2-core.h"
|
||||
#include "argon2-encoding.h"
|
||||
#include "argon2.h"
|
||||
|
||||
int argon2_ctx(argon2_context *context, argon2_type type) {
|
||||
int
|
||||
argon2_ctx(argon2_context *context, argon2_type type)
|
||||
{
|
||||
/* 1. Validate all inputs */
|
||||
int result = validate_inputs(context);
|
||||
uint32_t memory_blocks, segment_length;
|
||||
int result = validate_inputs(context);
|
||||
uint32_t memory_blocks, segment_length;
|
||||
argon2_instance_t instance;
|
||||
|
||||
if (ARGON2_OK != result) {
|
||||
@@ -49,14 +51,14 @@ int argon2_ctx(argon2_context *context, argon2_type type) {
|
||||
/* Ensure that all segments have equal length */
|
||||
memory_blocks = segment_length * (context->lanes * ARGON2_SYNC_POINTS);
|
||||
|
||||
instance.region = NULL;
|
||||
instance.passes = context->t_cost;
|
||||
instance.memory_blocks = memory_blocks;
|
||||
instance.region = 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.lane_length = segment_length * ARGON2_SYNC_POINTS;
|
||||
instance.lanes = context->lanes;
|
||||
instance.threads = context->threads;
|
||||
instance.type = type;
|
||||
|
||||
/* 3. Initialization: Hashing inputs, allocating memory, filling first
|
||||
* blocks
|
||||
@@ -80,15 +82,16 @@ int argon2_ctx(argon2_context *context, argon2_type type) {
|
||||
return ARGON2_OK;
|
||||
}
|
||||
|
||||
int argon2_hash(const uint32_t t_cost, const uint32_t m_cost,
|
||||
const uint32_t parallelism, const void *pwd,
|
||||
const size_t pwdlen, const void *salt, const size_t saltlen,
|
||||
void *hash, const size_t hashlen, char *encoded,
|
||||
const size_t encodedlen, argon2_type type) {
|
||||
|
||||
int
|
||||
argon2_hash(const uint32_t t_cost, const uint32_t m_cost,
|
||||
const uint32_t parallelism, const void *pwd, const size_t pwdlen,
|
||||
const void *salt, const size_t saltlen, void *hash,
|
||||
const size_t hashlen, char *encoded, const size_t encodedlen,
|
||||
argon2_type type)
|
||||
{
|
||||
argon2_context context;
|
||||
int result;
|
||||
uint8_t *out;
|
||||
int result;
|
||||
uint8_t * out;
|
||||
|
||||
if (pwdlen > ARGON2_MAX_PWD_LENGTH) {
|
||||
return ARGON2_PWD_TOO_LONG;
|
||||
@@ -107,21 +110,21 @@ int argon2_hash(const uint32_t t_cost, const uint32_t m_cost,
|
||||
return ARGON2_MEMORY_ALLOCATION_ERROR;
|
||||
}
|
||||
|
||||
context.out = (uint8_t *)out;
|
||||
context.outlen = (uint32_t)hashlen;
|
||||
context.pwd = (uint8_t *)pwd;
|
||||
context.pwdlen = (uint32_t)pwdlen;
|
||||
context.salt = (uint8_t *)salt;
|
||||
context.saltlen = (uint32_t)saltlen;
|
||||
context.secret = NULL;
|
||||
context.out = (uint8_t *) out;
|
||||
context.outlen = (uint32_t) hashlen;
|
||||
context.pwd = (uint8_t *) pwd;
|
||||
context.pwdlen = (uint32_t) pwdlen;
|
||||
context.salt = (uint8_t *) salt;
|
||||
context.saltlen = (uint32_t) 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 = parallelism;
|
||||
context.threads = parallelism;
|
||||
context.flags = ARGON2_DEFAULT_FLAGS;
|
||||
context.ad = NULL;
|
||||
context.adlen = 0;
|
||||
context.t_cost = t_cost;
|
||||
context.m_cost = m_cost;
|
||||
context.lanes = parallelism;
|
||||
context.threads = parallelism;
|
||||
context.flags = ARGON2_DEFAULT_FLAGS;
|
||||
|
||||
result = argon2_ctx(&context, type);
|
||||
|
||||
@@ -152,39 +155,42 @@ int argon2_hash(const uint32_t t_cost, const uint32_t m_cost,
|
||||
return ARGON2_OK;
|
||||
}
|
||||
|
||||
int argon2i_hash_encoded(const uint32_t t_cost, const uint32_t m_cost,
|
||||
const uint32_t parallelism, const void *pwd,
|
||||
const size_t pwdlen, const void *salt,
|
||||
const size_t saltlen, const size_t hashlen,
|
||||
char *encoded, const size_t encodedlen) {
|
||||
|
||||
int
|
||||
argon2i_hash_encoded(const uint32_t t_cost, const uint32_t m_cost,
|
||||
const uint32_t parallelism, const void *pwd,
|
||||
const size_t pwdlen, const void *salt,
|
||||
const size_t saltlen, const size_t hashlen, char *encoded,
|
||||
const size_t encodedlen)
|
||||
{
|
||||
return argon2_hash(t_cost, m_cost, parallelism, pwd, pwdlen, salt, saltlen,
|
||||
NULL, hashlen, encoded, encodedlen, Argon2_i);
|
||||
}
|
||||
|
||||
int argon2i_hash_raw(const uint32_t t_cost, const uint32_t m_cost,
|
||||
const uint32_t parallelism, const void *pwd,
|
||||
const size_t pwdlen, const void *salt,
|
||||
const size_t saltlen, void *hash, const size_t hashlen) {
|
||||
|
||||
int
|
||||
argon2i_hash_raw(const uint32_t t_cost, const uint32_t m_cost,
|
||||
const uint32_t parallelism, const void *pwd,
|
||||
const size_t pwdlen, const void *salt, const size_t saltlen,
|
||||
void *hash, const size_t hashlen)
|
||||
{
|
||||
return argon2_hash(t_cost, m_cost, parallelism, pwd, pwdlen, salt, saltlen,
|
||||
hash, hashlen, NULL, 0, Argon2_i);
|
||||
}
|
||||
|
||||
int argon2_verify(const char *encoded, const void *pwd, const size_t pwdlen,
|
||||
argon2_type type) {
|
||||
|
||||
int
|
||||
argon2_verify(const char *encoded, const void *pwd, const size_t pwdlen,
|
||||
argon2_type type)
|
||||
{
|
||||
argon2_context ctx;
|
||||
uint8_t *out;
|
||||
int decode_result;
|
||||
int ret;
|
||||
size_t encoded_len;
|
||||
uint8_t * out;
|
||||
int decode_result;
|
||||
int ret;
|
||||
size_t encoded_len;
|
||||
|
||||
memset(&ctx, 0, sizeof ctx);
|
||||
|
||||
ctx.pwd = NULL;
|
||||
ctx.pwdlen = 0;
|
||||
ctx.secret = NULL;
|
||||
ctx.pwd = NULL;
|
||||
ctx.pwdlen = 0;
|
||||
ctx.secret = NULL;
|
||||
ctx.secretlen = 0;
|
||||
|
||||
/* max values, to be updated in decode_string */
|
||||
@@ -192,13 +198,13 @@ int argon2_verify(const char *encoded, const void *pwd, const size_t pwdlen,
|
||||
if (encoded_len > UINT32_MAX) {
|
||||
return ARGON2_DECODING_LENGTH_FAIL;
|
||||
}
|
||||
ctx.adlen = (uint32_t) encoded_len;
|
||||
ctx.adlen = (uint32_t) encoded_len;
|
||||
ctx.saltlen = (uint32_t) encoded_len;
|
||||
ctx.outlen = (uint32_t) encoded_len;
|
||||
ctx.outlen = (uint32_t) encoded_len;
|
||||
|
||||
ctx.ad = (uint8_t *) malloc(ctx.adlen);
|
||||
ctx.ad = (uint8_t *) malloc(ctx.adlen);
|
||||
ctx.salt = (uint8_t *) malloc(ctx.saltlen);
|
||||
ctx.out = (uint8_t *) malloc(ctx.outlen);
|
||||
ctx.out = (uint8_t *) malloc(ctx.outlen);
|
||||
if (!ctx.out || !ctx.salt || !ctx.ad) {
|
||||
free(ctx.ad);
|
||||
free(ctx.salt);
|
||||
@@ -222,8 +228,8 @@ int argon2_verify(const char *encoded, const void *pwd, const size_t pwdlen,
|
||||
return decode_result;
|
||||
}
|
||||
|
||||
ret = argon2_hash(ctx.t_cost, ctx.m_cost, ctx.threads, pwd, pwdlen, ctx.salt,
|
||||
ctx.saltlen, out, ctx.outlen, NULL, 0, type);
|
||||
ret = argon2_hash(ctx.t_cost, ctx.m_cost, ctx.threads, pwd, pwdlen,
|
||||
ctx.salt, ctx.saltlen, out, ctx.outlen, NULL, 0, type);
|
||||
|
||||
free(ctx.ad);
|
||||
free(ctx.salt);
|
||||
@@ -237,6 +243,8 @@ int argon2_verify(const char *encoded, const void *pwd, const size_t pwdlen,
|
||||
return ret;
|
||||
}
|
||||
|
||||
int argon2i_verify(const char *encoded, const void *pwd, const size_t pwdlen) {
|
||||
int
|
||||
argon2i_verify(const char *encoded, const void *pwd, const size_t pwdlen)
|
||||
{
|
||||
return argon2_verify(encoded, pwd, pwdlen, Argon2_i);
|
||||
}
|
||||
|
||||
@@ -6,14 +6,15 @@
|
||||
* This work is licensed under a Creative Commons CC0 1.0 License/Waiver.
|
||||
*
|
||||
* You should have received a copy of the CC0 Public Domain Dedication along
|
||||
* with this software. If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.
|
||||
* with this software. If not, see
|
||||
* <http://creativecommons.org/publicdomain/zero/1.0/>.
|
||||
*/
|
||||
#ifndef argon2_H
|
||||
#define argon2_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include <limits.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
/*
|
||||
* Argon2 input parameter restrictions
|
||||
@@ -38,10 +39,11 @@
|
||||
#define ARGON2_MIN_MEMORY (2 * ARGON2_SYNC_POINTS) /* 2 blocks per slice */
|
||||
|
||||
#define ARGON2_MIN(a, b) ((a) < (b) ? (a) : (b))
|
||||
/* Max memory size is half the addressing space, topping at 2^32 blocks (4 TB) */
|
||||
#define ARGON2_MAX_MEMORY_BITS \
|
||||
/* Max memory size is half the addressing space, topping at 2^32 blocks (4 TB)
|
||||
*/
|
||||
#define ARGON2_MAX_MEMORY_BITS \
|
||||
ARGON2_MIN(UINT32_C(32), (sizeof(void *) * CHAR_BIT - 10 - 1))
|
||||
#define ARGON2_MAX_MEMORY \
|
||||
#define ARGON2_MAX_MEMORY \
|
||||
ARGON2_MIN(UINT32_C(0xFFFFFFFF), UINT64_C(1) << ARGON2_MAX_MEMORY_BITS)
|
||||
|
||||
/* Minimum and maximum number of passes */
|
||||
@@ -76,45 +78,45 @@ typedef enum Argon2_ErrorCodes {
|
||||
ARGON2_OUTPUT_PTR_NULL = -1,
|
||||
|
||||
ARGON2_OUTPUT_TOO_SHORT = -2,
|
||||
ARGON2_OUTPUT_TOO_LONG = -3,
|
||||
ARGON2_OUTPUT_TOO_LONG = -3,
|
||||
|
||||
ARGON2_PWD_TOO_SHORT = -4,
|
||||
ARGON2_PWD_TOO_LONG = -5,
|
||||
ARGON2_PWD_TOO_LONG = -5,
|
||||
|
||||
ARGON2_SALT_TOO_SHORT = -6,
|
||||
ARGON2_SALT_TOO_LONG = -7,
|
||||
ARGON2_SALT_TOO_LONG = -7,
|
||||
|
||||
ARGON2_AD_TOO_SHORT = -8,
|
||||
ARGON2_AD_TOO_LONG = -9,
|
||||
ARGON2_AD_TOO_LONG = -9,
|
||||
|
||||
ARGON2_SECRET_TOO_SHORT = -10,
|
||||
ARGON2_SECRET_TOO_LONG = -11,
|
||||
ARGON2_SECRET_TOO_LONG = -11,
|
||||
|
||||
ARGON2_TIME_TOO_SMALL = -12,
|
||||
ARGON2_TIME_TOO_LARGE = -13,
|
||||
|
||||
ARGON2_MEMORY_TOO_LITTLE = -14,
|
||||
ARGON2_MEMORY_TOO_MUCH = -15,
|
||||
ARGON2_MEMORY_TOO_MUCH = -15,
|
||||
|
||||
ARGON2_LANES_TOO_FEW = -16,
|
||||
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_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_AD_PTR_MISMATCH = -21, /* NULL ptr with non-zero length */
|
||||
|
||||
ARGON2_MEMORY_ALLOCATION_ERROR = -22,
|
||||
|
||||
ARGON2_FREE_MEMORY_CBK_NULL = -23,
|
||||
ARGON2_FREE_MEMORY_CBK_NULL = -23,
|
||||
ARGON2_ALLOCATE_MEMORY_CBK_NULL = -24,
|
||||
|
||||
ARGON2_INCORRECT_PARAMETER = -25,
|
||||
ARGON2_INCORRECT_TYPE = -26,
|
||||
ARGON2_INCORRECT_TYPE = -26,
|
||||
|
||||
ARGON2_OUT_PTR_MISMATCH = -27,
|
||||
|
||||
ARGON2_THREADS_TOO_FEW = -28,
|
||||
ARGON2_THREADS_TOO_FEW = -28,
|
||||
ARGON2_THREADS_TOO_MANY = -29,
|
||||
|
||||
ARGON2_MISSING_ARGS = -30,
|
||||
@@ -148,9 +150,12 @@ typedef enum Argon2_ErrorCodes {
|
||||
* are pre-hashed (and thus not needed anymore), and the entire memory
|
||||
*****
|
||||
* Simplest situation: you have output array out[8], password is stored in
|
||||
* pwd[32], salt is stored in salt[16], you do not have keys nor associated data.
|
||||
* You need to spend 1 GB of RAM and you run 5 passes of Argon2 with 4 parallel lanes.
|
||||
* You want to erase the password, but you're OK with last pass not being erased.
|
||||
* pwd[32], salt is stored in salt[16], you do not have keys nor associated
|
||||
*data.
|
||||
* You need to spend 1 GB of RAM and you run 5 passes of Argon2 with 4 parallel
|
||||
*lanes.
|
||||
* You want to erase the password, but you're OK with last pass not being
|
||||
*erased.
|
||||
* You want to use the default memory allocator.
|
||||
* 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).
|
||||
|
||||
@@ -4,63 +4,63 @@
|
||||
#include <string.h>
|
||||
|
||||
#include "crypto_generichash_blake2b.h"
|
||||
#include "utils.h"
|
||||
#include "private/common.h"
|
||||
#include "utils.h"
|
||||
|
||||
#include "blake2b-long.h"
|
||||
|
||||
int blake2b_long(void *pout, size_t outlen, const void *in, size_t inlen) {
|
||||
uint8_t *out = (uint8_t *)pout;
|
||||
int
|
||||
blake2b_long(void *pout, size_t outlen, const void *in, size_t inlen)
|
||||
{
|
||||
uint8_t * out = (uint8_t *) pout;
|
||||
crypto_generichash_blake2b_state blake_state;
|
||||
uint8_t outlen_bytes[4 /* sizeof(uint32_t) */] = {0};
|
||||
int ret = -1;
|
||||
uint8_t outlen_bytes[4 /* sizeof(uint32_t) */] = { 0 };
|
||||
int ret = -1;
|
||||
|
||||
if (outlen > UINT32_MAX) {
|
||||
goto fail; /* LCOV_EXCL_LINE */
|
||||
}
|
||||
|
||||
/* Ensure little-endian byte order! */
|
||||
STORE32_LE(outlen_bytes, (uint32_t)outlen);
|
||||
STORE32_LE(outlen_bytes, (uint32_t) outlen);
|
||||
|
||||
#define TRY(statement) \
|
||||
do { \
|
||||
ret = statement; \
|
||||
if (ret < 0) { \
|
||||
goto fail; \
|
||||
} \
|
||||
} while ((void)0, 0)
|
||||
#define TRY(statement) \
|
||||
do { \
|
||||
ret = statement; \
|
||||
if (ret < 0) { \
|
||||
goto fail; \
|
||||
} \
|
||||
} while ((void) 0, 0)
|
||||
|
||||
if (outlen <= crypto_generichash_blake2b_BYTES_MAX) {
|
||||
TRY(crypto_generichash_blake2b_init(&blake_state, NULL, 0U, outlen));
|
||||
TRY(crypto_generichash_blake2b_update(&blake_state, outlen_bytes,
|
||||
sizeof(outlen_bytes)));
|
||||
TRY(crypto_generichash_blake2b_update(&blake_state,
|
||||
(const unsigned char *) in,
|
||||
inlen));
|
||||
TRY(crypto_generichash_blake2b_update(
|
||||
&blake_state, (const unsigned char *) in, inlen));
|
||||
TRY(crypto_generichash_blake2b_final(&blake_state, out, outlen));
|
||||
} else {
|
||||
uint32_t toproduce;
|
||||
uint8_t out_buffer[crypto_generichash_blake2b_BYTES_MAX];
|
||||
uint8_t in_buffer[crypto_generichash_blake2b_BYTES_MAX];
|
||||
TRY(crypto_generichash_blake2b_init(&blake_state, NULL, 0U,
|
||||
crypto_generichash_blake2b_BYTES_MAX));
|
||||
uint8_t out_buffer[crypto_generichash_blake2b_BYTES_MAX];
|
||||
uint8_t in_buffer[crypto_generichash_blake2b_BYTES_MAX];
|
||||
TRY(crypto_generichash_blake2b_init(
|
||||
&blake_state, NULL, 0U, crypto_generichash_blake2b_BYTES_MAX));
|
||||
TRY(crypto_generichash_blake2b_update(&blake_state, outlen_bytes,
|
||||
sizeof(outlen_bytes)));
|
||||
TRY(crypto_generichash_blake2b_update(&blake_state,
|
||||
(const unsigned char *) in,
|
||||
inlen));
|
||||
TRY(crypto_generichash_blake2b_final(&blake_state, out_buffer,
|
||||
crypto_generichash_blake2b_BYTES_MAX));
|
||||
TRY(crypto_generichash_blake2b_update(
|
||||
&blake_state, (const unsigned char *) in, inlen));
|
||||
TRY(crypto_generichash_blake2b_final(
|
||||
&blake_state, out_buffer, crypto_generichash_blake2b_BYTES_MAX));
|
||||
memcpy(out, out_buffer, crypto_generichash_blake2b_BYTES_MAX / 2);
|
||||
out += crypto_generichash_blake2b_BYTES_MAX / 2;
|
||||
toproduce = (uint32_t)outlen - crypto_generichash_blake2b_BYTES_MAX / 2;
|
||||
toproduce =
|
||||
(uint32_t) outlen - crypto_generichash_blake2b_BYTES_MAX / 2;
|
||||
|
||||
while (toproduce > crypto_generichash_blake2b_BYTES_MAX) {
|
||||
memcpy(in_buffer, out_buffer, crypto_generichash_blake2b_BYTES_MAX);
|
||||
TRY(crypto_generichash_blake2b(out_buffer, crypto_generichash_blake2b_BYTES_MAX,
|
||||
in_buffer,
|
||||
crypto_generichash_blake2b_BYTES_MAX,
|
||||
NULL, 0U));
|
||||
TRY(crypto_generichash_blake2b(
|
||||
out_buffer, crypto_generichash_blake2b_BYTES_MAX, in_buffer,
|
||||
crypto_generichash_blake2b_BYTES_MAX, NULL, 0U));
|
||||
memcpy(out, out_buffer, crypto_generichash_blake2b_BYTES_MAX / 2);
|
||||
out += crypto_generichash_blake2b_BYTES_MAX / 2;
|
||||
toproduce -= crypto_generichash_blake2b_BYTES_MAX / 2;
|
||||
|
||||
@@ -4,35 +4,37 @@
|
||||
#include "private/common.h"
|
||||
|
||||
/*designed by the Lyra PHC team */
|
||||
static inline uint64_t fBlaMka(uint64_t x, uint64_t y) {
|
||||
const uint64_t m = UINT64_C(0xFFFFFFFF);
|
||||
static inline uint64_t
|
||||
fBlaMka(uint64_t x, uint64_t y)
|
||||
{
|
||||
const uint64_t m = UINT64_C(0xFFFFFFFF);
|
||||
const uint64_t xy = (x & m) * (y & m);
|
||||
return x + y + 2 * xy;
|
||||
}
|
||||
|
||||
#define G(a, b, c, d) \
|
||||
do { \
|
||||
a = fBlaMka(a, b); \
|
||||
d = ROTR64(d ^ a, 32); \
|
||||
c = fBlaMka(c, d); \
|
||||
b = ROTR64(b ^ c, 24); \
|
||||
a = fBlaMka(a, b); \
|
||||
d = ROTR64(d ^ a, 16); \
|
||||
c = fBlaMka(c, d); \
|
||||
b = ROTR64(b ^ c, 63); \
|
||||
} while ((void)0, 0)
|
||||
#define G(a, b, c, d) \
|
||||
do { \
|
||||
a = fBlaMka(a, b); \
|
||||
d = ROTR64(d ^ a, 32); \
|
||||
c = fBlaMka(c, d); \
|
||||
b = ROTR64(b ^ c, 24); \
|
||||
a = fBlaMka(a, b); \
|
||||
d = ROTR64(d ^ a, 16); \
|
||||
c = fBlaMka(c, d); \
|
||||
b = ROTR64(b ^ c, 63); \
|
||||
} while ((void) 0, 0)
|
||||
|
||||
#define BLAKE2_ROUND_NOMSG(v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, \
|
||||
v12, v13, v14, v15) \
|
||||
do { \
|
||||
G(v0, v4, v8, v12); \
|
||||
G(v1, v5, v9, v13); \
|
||||
G(v2, v6, v10, v14); \
|
||||
G(v3, v7, v11, v15); \
|
||||
G(v0, v5, v10, v15); \
|
||||
G(v1, v6, v11, v12); \
|
||||
G(v2, v7, v8, v13); \
|
||||
G(v3, v4, v9, v14); \
|
||||
} while ((void)0, 0)
|
||||
#define BLAKE2_ROUND_NOMSG(v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, \
|
||||
v12, v13, v14, v15) \
|
||||
do { \
|
||||
G(v0, v4, v8, v12); \
|
||||
G(v1, v5, v9, v13); \
|
||||
G(v2, v6, v10, v14); \
|
||||
G(v3, v7, v11, v15); \
|
||||
G(v0, v5, v10, v15); \
|
||||
G(v1, v6, v11, v12); \
|
||||
G(v2, v7, v8, v13); \
|
||||
G(v3, v4, v9, v14); \
|
||||
} while ((void) 0, 0)
|
||||
|
||||
#endif
|
||||
|
||||
@@ -3,115 +3,117 @@
|
||||
|
||||
#include "private/common.h"
|
||||
|
||||
#define r16 \
|
||||
#define r16 \
|
||||
(_mm_setr_epi8(2, 3, 4, 5, 6, 7, 0, 1, 10, 11, 12, 13, 14, 15, 8, 9))
|
||||
#define r24 \
|
||||
#define r24 \
|
||||
(_mm_setr_epi8(3, 4, 5, 6, 7, 0, 1, 2, 11, 12, 13, 14, 15, 8, 9, 10))
|
||||
#define _mm_roti_epi64(x, c) \
|
||||
(-(c) == 32) \
|
||||
? _mm_shuffle_epi32((x), _MM_SHUFFLE(2, 3, 0, 1)) \
|
||||
: (-(c) == 24) \
|
||||
? _mm_shuffle_epi8((x), r24) \
|
||||
: (-(c) == 16) \
|
||||
? _mm_shuffle_epi8((x), r16) \
|
||||
: (-(c) == 63) \
|
||||
? _mm_xor_si128(_mm_srli_epi64((x), -(c)), \
|
||||
_mm_add_epi64((x), (x))) \
|
||||
: _mm_xor_si128(_mm_srli_epi64((x), -(c)), \
|
||||
#define _mm_roti_epi64(x, c) \
|
||||
(-(c) == 32) \
|
||||
? _mm_shuffle_epi32((x), _MM_SHUFFLE(2, 3, 0, 1)) \
|
||||
: (-(c) == 24) \
|
||||
? _mm_shuffle_epi8((x), r24) \
|
||||
: (-(c) == 16) \
|
||||
? _mm_shuffle_epi8((x), r16) \
|
||||
: (-(c) == 63) \
|
||||
? _mm_xor_si128(_mm_srli_epi64((x), -(c)), \
|
||||
_mm_add_epi64((x), (x))) \
|
||||
: _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));
|
||||
}
|
||||
|
||||
#define G1(A0, B0, C0, D0, A1, B1, C1, D1) \
|
||||
do { \
|
||||
A0 = fBlaMka(A0, B0); \
|
||||
A1 = fBlaMka(A1, B1); \
|
||||
\
|
||||
D0 = _mm_xor_si128(D0, A0); \
|
||||
D1 = _mm_xor_si128(D1, A1); \
|
||||
\
|
||||
D0 = _mm_roti_epi64(D0, -32); \
|
||||
D1 = _mm_roti_epi64(D1, -32); \
|
||||
\
|
||||
C0 = fBlaMka(C0, D0); \
|
||||
C1 = fBlaMka(C1, D1); \
|
||||
\
|
||||
B0 = _mm_xor_si128(B0, C0); \
|
||||
B1 = _mm_xor_si128(B1, C1); \
|
||||
\
|
||||
B0 = _mm_roti_epi64(B0, -24); \
|
||||
B1 = _mm_roti_epi64(B1, -24); \
|
||||
} while ((void)0, 0)
|
||||
#define G1(A0, B0, C0, D0, A1, B1, C1, D1) \
|
||||
do { \
|
||||
A0 = fBlaMka(A0, B0); \
|
||||
A1 = fBlaMka(A1, B1); \
|
||||
\
|
||||
D0 = _mm_xor_si128(D0, A0); \
|
||||
D1 = _mm_xor_si128(D1, A1); \
|
||||
\
|
||||
D0 = _mm_roti_epi64(D0, -32); \
|
||||
D1 = _mm_roti_epi64(D1, -32); \
|
||||
\
|
||||
C0 = fBlaMka(C0, D0); \
|
||||
C1 = fBlaMka(C1, D1); \
|
||||
\
|
||||
B0 = _mm_xor_si128(B0, C0); \
|
||||
B1 = _mm_xor_si128(B1, C1); \
|
||||
\
|
||||
B0 = _mm_roti_epi64(B0, -24); \
|
||||
B1 = _mm_roti_epi64(B1, -24); \
|
||||
} while ((void) 0, 0)
|
||||
|
||||
#define G2(A0, B0, C0, D0, A1, B1, C1, D1) \
|
||||
do { \
|
||||
A0 = fBlaMka(A0, B0); \
|
||||
A1 = fBlaMka(A1, B1); \
|
||||
\
|
||||
D0 = _mm_xor_si128(D0, A0); \
|
||||
D1 = _mm_xor_si128(D1, A1); \
|
||||
\
|
||||
D0 = _mm_roti_epi64(D0, -16); \
|
||||
D1 = _mm_roti_epi64(D1, -16); \
|
||||
\
|
||||
C0 = fBlaMka(C0, D0); \
|
||||
C1 = fBlaMka(C1, D1); \
|
||||
\
|
||||
B0 = _mm_xor_si128(B0, C0); \
|
||||
B1 = _mm_xor_si128(B1, C1); \
|
||||
\
|
||||
B0 = _mm_roti_epi64(B0, -63); \
|
||||
B1 = _mm_roti_epi64(B1, -63); \
|
||||
} while ((void)0, 0)
|
||||
#define G2(A0, B0, C0, D0, A1, B1, C1, D1) \
|
||||
do { \
|
||||
A0 = fBlaMka(A0, B0); \
|
||||
A1 = fBlaMka(A1, B1); \
|
||||
\
|
||||
D0 = _mm_xor_si128(D0, A0); \
|
||||
D1 = _mm_xor_si128(D1, A1); \
|
||||
\
|
||||
D0 = _mm_roti_epi64(D0, -16); \
|
||||
D1 = _mm_roti_epi64(D1, -16); \
|
||||
\
|
||||
C0 = fBlaMka(C0, D0); \
|
||||
C1 = fBlaMka(C1, D1); \
|
||||
\
|
||||
B0 = _mm_xor_si128(B0, C0); \
|
||||
B1 = _mm_xor_si128(B1, C1); \
|
||||
\
|
||||
B0 = _mm_roti_epi64(B0, -63); \
|
||||
B1 = _mm_roti_epi64(B1, -63); \
|
||||
} while ((void) 0, 0)
|
||||
|
||||
#define DIAGONALIZE(A0, B0, C0, D0, A1, B1, C1, D1) \
|
||||
do { \
|
||||
__m128i t0 = _mm_alignr_epi8(B1, B0, 8); \
|
||||
__m128i t1 = _mm_alignr_epi8(B0, B1, 8); \
|
||||
B0 = t0; \
|
||||
B1 = t1; \
|
||||
\
|
||||
t0 = C0; \
|
||||
C0 = C1; \
|
||||
C1 = t0; \
|
||||
\
|
||||
t0 = _mm_alignr_epi8(D1, D0, 8); \
|
||||
t1 = _mm_alignr_epi8(D0, D1, 8); \
|
||||
D0 = t1; \
|
||||
D1 = t0; \
|
||||
} while ((void)0, 0)
|
||||
#define DIAGONALIZE(A0, B0, C0, D0, A1, B1, C1, D1) \
|
||||
do { \
|
||||
__m128i t0 = _mm_alignr_epi8(B1, B0, 8); \
|
||||
__m128i t1 = _mm_alignr_epi8(B0, B1, 8); \
|
||||
B0 = t0; \
|
||||
B1 = t1; \
|
||||
\
|
||||
t0 = C0; \
|
||||
C0 = C1; \
|
||||
C1 = t0; \
|
||||
\
|
||||
t0 = _mm_alignr_epi8(D1, D0, 8); \
|
||||
t1 = _mm_alignr_epi8(D0, D1, 8); \
|
||||
D0 = t1; \
|
||||
D1 = t0; \
|
||||
} while ((void) 0, 0)
|
||||
|
||||
#define UNDIAGONALIZE(A0, B0, C0, D0, A1, B1, C1, D1) \
|
||||
do { \
|
||||
__m128i t0 = _mm_alignr_epi8(B0, B1, 8); \
|
||||
__m128i t1 = _mm_alignr_epi8(B1, B0, 8); \
|
||||
B0 = t0; \
|
||||
B1 = t1; \
|
||||
\
|
||||
t0 = C0; \
|
||||
C0 = C1; \
|
||||
C1 = t0; \
|
||||
\
|
||||
t0 = _mm_alignr_epi8(D0, D1, 8); \
|
||||
t1 = _mm_alignr_epi8(D1, D0, 8); \
|
||||
D0 = t1; \
|
||||
D1 = t0; \
|
||||
} while ((void)0, 0)
|
||||
#define UNDIAGONALIZE(A0, B0, C0, D0, A1, B1, C1, D1) \
|
||||
do { \
|
||||
__m128i t0 = _mm_alignr_epi8(B0, B1, 8); \
|
||||
__m128i t1 = _mm_alignr_epi8(B1, B0, 8); \
|
||||
B0 = t0; \
|
||||
B1 = t1; \
|
||||
\
|
||||
t0 = C0; \
|
||||
C0 = C1; \
|
||||
C1 = t0; \
|
||||
\
|
||||
t0 = _mm_alignr_epi8(D0, D1, 8); \
|
||||
t1 = _mm_alignr_epi8(D1, D0, 8); \
|
||||
D0 = t1; \
|
||||
D1 = t0; \
|
||||
} while ((void) 0, 0)
|
||||
|
||||
#define BLAKE2_ROUND(A0, A1, B0, B1, C0, C1, D0, D1) \
|
||||
do { \
|
||||
G1(A0, B0, C0, D0, A1, B1, C1, D1); \
|
||||
G2(A0, B0, C0, D0, A1, B1, C1, D1); \
|
||||
\
|
||||
DIAGONALIZE(A0, B0, C0, D0, A1, B1, C1, D1); \
|
||||
\
|
||||
G1(A0, B0, C0, D0, A1, B1, C1, D1); \
|
||||
G2(A0, B0, C0, D0, A1, B1, C1, D1); \
|
||||
\
|
||||
UNDIAGONALIZE(A0, B0, C0, D0, A1, B1, C1, D1); \
|
||||
} while ((void)0, 0)
|
||||
#define BLAKE2_ROUND(A0, A1, B0, B1, C0, C1, D0, D1) \
|
||||
do { \
|
||||
G1(A0, B0, C0, D0, A1, B1, C1, D1); \
|
||||
G2(A0, B0, C0, D0, A1, B1, C1, D1); \
|
||||
\
|
||||
DIAGONALIZE(A0, B0, C0, D0, A1, B1, C1, D1); \
|
||||
\
|
||||
G1(A0, B0, C0, D0, A1, B1, C1, D1); \
|
||||
G2(A0, B0, C0, D0, A1, B1, C1, D1); \
|
||||
\
|
||||
UNDIAGONALIZE(A0, B0, C0, D0, A1, B1, C1, D1); \
|
||||
} while ((void) 0, 0)
|
||||
|
||||
#endif
|
||||
|
||||
@@ -5,8 +5,8 @@
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "argon2.h"
|
||||
#include "argon2-core.h"
|
||||
#include "argon2.h"
|
||||
#include "crypto_pwhash_argon2i.h"
|
||||
#include "randombytes.h"
|
||||
#include "utils.h"
|
||||
@@ -55,7 +55,7 @@ crypto_pwhash_argon2i_strbytes(void)
|
||||
return crypto_pwhash_argon2i_STRBYTES;
|
||||
}
|
||||
|
||||
const char *
|
||||
const char*
|
||||
crypto_pwhash_argon2i_strprefix(void)
|
||||
{
|
||||
return crypto_pwhash_argon2i_STRPREFIX;
|
||||
@@ -122,13 +122,10 @@ crypto_pwhash_argon2i_memlimit_sensitive(void)
|
||||
}
|
||||
|
||||
int
|
||||
crypto_pwhash_argon2i(unsigned char * const out,
|
||||
unsigned long long outlen,
|
||||
const char * const passwd,
|
||||
unsigned long long passwdlen,
|
||||
const unsigned char * const salt,
|
||||
unsigned long long opslimit,
|
||||
size_t memlimit, int alg)
|
||||
crypto_pwhash_argon2i(unsigned char* const out, unsigned long long outlen,
|
||||
const char* const passwd, unsigned long long passwdlen,
|
||||
const unsigned char* const salt,
|
||||
unsigned long long opslimit, size_t memlimit, int alg)
|
||||
{
|
||||
memset(out, 0, outlen);
|
||||
if (alg != crypto_pwhash_argon2i_ALG_ARGON2I13) {
|
||||
@@ -146,40 +143,39 @@ crypto_pwhash_argon2i(unsigned char * const out,
|
||||
return -1;
|
||||
}
|
||||
if (argon2i_hash_raw((uint32_t) opslimit, (uint32_t) memlimit,
|
||||
(uint32_t) 1U, passwd, (size_t) passwdlen,
|
||||
salt, (size_t) crypto_pwhash_argon2i_SALTBYTES,
|
||||
out, (size_t) outlen) != ARGON2_OK) {
|
||||
(uint32_t) 1U, passwd, (size_t) passwdlen, salt,
|
||||
(size_t) crypto_pwhash_argon2i_SALTBYTES, out,
|
||||
(size_t) outlen) != ARGON2_OK) {
|
||||
return -1; /* LCOV_EXCL_LINE */
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
crypto_pwhash_argon2i_str(char out[crypto_pwhash_argon2i_STRBYTES],
|
||||
const char * const passwd,
|
||||
crypto_pwhash_argon2i_str(char out[crypto_pwhash_argon2i_STRBYTES],
|
||||
const char* const passwd,
|
||||
unsigned long long passwdlen,
|
||||
unsigned long long opslimit,
|
||||
size_t memlimit)
|
||||
unsigned long long opslimit, size_t memlimit)
|
||||
{
|
||||
unsigned char salt[crypto_pwhash_argon2i_SALTBYTES];
|
||||
|
||||
memset(out, 0, crypto_pwhash_argon2i_STRBYTES);
|
||||
memlimit /= 1024U;
|
||||
if (passwdlen > ARGON2_MAX_PWD_LENGTH ||
|
||||
opslimit > ARGON2_MAX_TIME || memlimit > ARGON2_MAX_MEMORY) {
|
||||
if (passwdlen > ARGON2_MAX_PWD_LENGTH || opslimit > ARGON2_MAX_TIME ||
|
||||
memlimit > ARGON2_MAX_MEMORY) {
|
||||
errno = EFBIG;
|
||||
return -1;
|
||||
}
|
||||
if (passwdlen < ARGON2_MIN_PWD_LENGTH ||
|
||||
opslimit < ARGON2_MIN_TIME || memlimit < ARGON2_MIN_MEMORY) {
|
||||
if (passwdlen < ARGON2_MIN_PWD_LENGTH || opslimit < ARGON2_MIN_TIME ||
|
||||
memlimit < ARGON2_MIN_MEMORY) {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
randombytes_buf(salt, sizeof salt);
|
||||
if (argon2i_hash_encoded((uint32_t) opslimit, (uint32_t) memlimit,
|
||||
(uint32_t) 1U, passwd, (size_t) passwdlen,
|
||||
salt, sizeof salt, STR_HASHBYTES,
|
||||
out, crypto_pwhash_argon2i_STRBYTES) != ARGON2_OK) {
|
||||
(uint32_t) 1U, passwd, (size_t) passwdlen, salt,
|
||||
sizeof salt, STR_HASHBYTES, out,
|
||||
crypto_pwhash_argon2i_STRBYTES) != ARGON2_OK) {
|
||||
return -1; /* LCOV_EXCL_LINE */
|
||||
}
|
||||
return 0;
|
||||
@@ -187,19 +183,19 @@ crypto_pwhash_argon2i_str(char out[crypto_pwhash_argon2i_STRBYTES],
|
||||
|
||||
int
|
||||
crypto_pwhash_argon2i_str_verify(const char str[crypto_pwhash_argon2i_STRBYTES],
|
||||
const char * const passwd,
|
||||
const char* const passwd,
|
||||
unsigned long long passwdlen)
|
||||
{
|
||||
if (passwdlen > ARGON2_MAX_PWD_LENGTH) {
|
||||
errno = EFBIG;
|
||||
return -1;
|
||||
}
|
||||
/* LCOV_EXCL_START */
|
||||
/* LCOV_EXCL_START */
|
||||
if (passwdlen < ARGON2_MIN_PWD_LENGTH) {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
/* LCOV_EXCL_STOP */
|
||||
/* LCOV_EXCL_STOP */
|
||||
if (argon2i_verify(str, passwd, (size_t) passwdlen) != ARGON2_OK) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user