Update Argon2 for style

- Make sure notice licenses are embedded
- Remove copyright and docs from headers
This commit is contained in:
Justine Tunney 2022-03-21 07:25:48 -07:00
parent f78f2fcac3
commit 4881ae7527
11 changed files with 613 additions and 711 deletions

View file

@ -1,28 +1,39 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:4;tab-width:8;coding:utf-8 -*-│
vi: set net ft=c ts=4 sts=4 sw=4 fenc=utf-8 :vi
Argon2 reference source code package - reference C implementations
Copyright 2015
Daniel Dinu, Dmitry Khovratovich, Jean-Philippe Aumasson, and Samuel Neves
You may use this work under the terms of a Creative Commons CC0 1.0
License/Waiver or the Apache Public License 2.0, at your option. The
terms of these licenses can be found at:
- CC0 1.0 Universal : https://creativecommons.org/publicdomain/zero/1.0 │
- Apache 2.0 : https://www.apache.org/licenses/LICENSE-2.0 │
*/
#include "libc/limits.h" #include "libc/limits.h"
#include "libc/mem/mem.h" #include "libc/mem/mem.h"
#include "libc/str/str.h" #include "libc/str/str.h"
#include "third_party/argon2/argon2.h" #include "third_party/argon2/argon2.h"
#include "third_party/argon2/core.h" #include "third_party/argon2/core.h"
#include "third_party/argon2/encoding.h" #include "third_party/argon2/encoding.h"
asm(".ident\t\"\\n\\n\
argon2 (CC0 or Apache2)\\n\
Copyright 2016 Daniel Dinu, Dmitry Khovratovich\\n\
Copyright 2016 Jean-Philippe Aumasson, Samuel Neves\"");
/* clang-format off */ /* clang-format off */
/* /**
* Argon2 reference source code package - reference C implementations * Function that gives the string representation of an argon2_type.
* * @param type The argon2_type that we want the string for
* Copyright 2015 * @param uppercase Whether the string should have the first letter uppercase
* Daniel Dinu, Dmitry Khovratovich, Jean-Philippe Aumasson, and Samuel Neves * @return NULL if invalid type, otherwise the string representation.
*
* You may use this work under the terms of a Creative Commons CC0 1.0
* License/Waiver or the Apache Public License 2.0, at your option. The terms of
* these licenses can be found at:
*
* - CC0 1.0 Universal : https://creativecommons.org/publicdomain/zero/1.0
* - Apache 2.0 : https://www.apache.org/licenses/LICENSE-2.0
*
* You should have received a copy of both of these licenses along with this
* software. If not, they may be obtained at the above URLs.
*/ */
const char *argon2_type2string(argon2_type type, int uppercase) { const char *argon2_type2string(argon2_type type, int uppercase) {
switch (type) { switch (type) {
case Argon2_d: case Argon2_d:
@ -32,10 +43,14 @@ const char *argon2_type2string(argon2_type type, int uppercase) {
case Argon2_id: case Argon2_id:
return uppercase ? "Argon2id" : "argon2id"; return uppercase ? "Argon2id" : "argon2id";
} }
return NULL; return NULL;
} }
/**
* 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_ctx(argon2_context *context, argon2_type type) { int argon2_ctx(argon2_context *context, argon2_type type) {
/* 1. Validate all inputs */ /* 1. Validate all inputs */
int result = validate_inputs(context); int result = validate_inputs(context);
@ -131,9 +146,9 @@ int argon2_hash(const uint32_t t_cost, const uint32_t m_cost,
context.out = (uint8_t *)out; context.out = (uint8_t *)out;
context.outlen = (uint32_t)hashlen; context.outlen = (uint32_t)hashlen;
context.pwd = CONST_CAST(uint8_t *)pwd; context.pwd = (uint8_t *)(uintptr_t)pwd;
context.pwdlen = (uint32_t)pwdlen; context.pwdlen = (uint32_t)pwdlen;
context.salt = CONST_CAST(uint8_t *)salt; context.salt = (uint8_t *)(uintptr_t)salt;
context.saltlen = (uint32_t)saltlen; context.saltlen = (uint32_t)saltlen;
context.secret = NULL; context.secret = NULL;
context.secretlen = 0; context.secretlen = 0;
@ -176,6 +191,21 @@ int argon2_hash(const uint32_t t_cost, const uint32_t m_cost,
return ARGON2_OK; return ARGON2_OK;
} }
/**
* Hashes a password with Argon2i, producing an encoded hash
* @param t_cost Number of iterations
* @param m_cost Sets memory usage to m_cost kibibytes
* @param parallelism Number of threads and compute lanes
* @param pwd Pointer to password
* @param pwdlen Password size in bytes
* @param salt Pointer to salt
* @param saltlen Salt size in bytes
* @param hashlen Desired length of the hash in bytes
* @param encoded Buffer where to write the encoded hash
* @param encodedlen Size of the buffer (thus max size of the encoded hash)
* @pre Different parallelism levels will give different results
* @pre Returns ARGON2_OK if successful
*/
int argon2i_hash_encoded(const uint32_t t_cost, const uint32_t m_cost, int argon2i_hash_encoded(const uint32_t t_cost, const uint32_t m_cost,
const uint32_t parallelism, const void *pwd, const uint32_t parallelism, const void *pwd,
const size_t pwdlen, const void *salt, const size_t pwdlen, const void *salt,
@ -187,6 +217,20 @@ int argon2i_hash_encoded(const uint32_t t_cost, const uint32_t m_cost,
ARGON2_VERSION_NUMBER); ARGON2_VERSION_NUMBER);
} }
/**
* Hashes a password with Argon2i, producing a raw hash at @hash
* @param t_cost Number of iterations
* @param m_cost Sets memory usage to m_cost kibibytes
* @param parallelism Number of threads and compute lanes
* @param pwd Pointer to password
* @param pwdlen Password size in bytes
* @param salt Pointer to salt
* @param saltlen Salt size in bytes
* @param hash Buffer where to write the raw hash - updated by the function
* @param hashlen Desired length of the hash in bytes
* @pre Different parallelism levels will give different results
* @pre Returns ARGON2_OK if successful
*/
int argon2i_hash_raw(const uint32_t t_cost, const uint32_t m_cost, int argon2i_hash_raw(const uint32_t t_cost, const uint32_t m_cost,
const uint32_t parallelism, const void *pwd, const uint32_t parallelism, const void *pwd,
const size_t pwdlen, const void *salt, const size_t pwdlen, const void *salt,
@ -251,9 +295,7 @@ int argon2_verify(const char *encoded, const void *pwd, const size_t pwdlen,
argon2_context ctx; argon2_context ctx;
uint8_t *desired_result = NULL; uint8_t *desired_result = NULL;
int ret = ARGON2_OK; int ret = ARGON2_OK;
size_t encoded_len; size_t encoded_len;
uint32_t max_field_len; uint32_t max_field_len;
@ -312,6 +354,13 @@ fail:
return ret; return ret;
} }
/**
* Verifies a password against an encoded string
* Encoded string is restricted as in validate_inputs()
* @param encoded String encoding parameters, salt, hash
* @param pwd Pointer to password
* @pre Returns ARGON2_OK if successful
*/
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); return argon2_verify(encoded, pwd, pwdlen, Argon2_i);
@ -327,14 +376,39 @@ int argon2id_verify(const char *encoded, const void *pwd, const size_t pwdlen) {
return argon2_verify(encoded, pwd, pwdlen, Argon2_id); return argon2_verify(encoded, pwd, pwdlen, Argon2_id);
} }
/**
* Argon2d: Version of Argon2 that picks memory blocks depending
* on the password and salt. Only for side-channel-free
* environment!!
*****
* @param context Pointer to current Argon2 context
* @return Zero if successful, a non zero error code otherwise
*/
int argon2d_ctx(argon2_context *context) { int argon2d_ctx(argon2_context *context) {
return argon2_ctx(context, Argon2_d); return argon2_ctx(context, Argon2_d);
} }
/**
* Argon2i: Version of Argon2 that picks memory blocks
* independent on the password and salt. Good for side-channels,
* but worse w.r.t. tradeoff attacks if only one pass is used.
*****
* @param context Pointer to current Argon2 context
* @return Zero if successful, a non zero error code otherwise
*/
int argon2i_ctx(argon2_context *context) { int argon2i_ctx(argon2_context *context) {
return argon2_ctx(context, Argon2_i); return argon2_ctx(context, Argon2_i);
} }
/**
* Argon2id: Version of Argon2 where the first half-pass over memory is
* password-independent, the rest are password-dependent (on the password and
* salt). OK against side channels (they reduce to 1/2-pass Argon2i), and
* better with w.r.t. tradeoff attacks (similar to Argon2d).
*****
* @param context Pointer to current Argon2 context
* @return Zero if successful, a non zero error code otherwise
*/
int argon2id_ctx(argon2_context *context) { int argon2id_ctx(argon2_context *context) {
return argon2_ctx(context, Argon2_id); return argon2_ctx(context, Argon2_id);
} }
@ -353,18 +427,43 @@ int argon2_verify_ctx(argon2_context *context, const char *hash,
return ARGON2_OK; return ARGON2_OK;
} }
/**
* Verify if a given password is correct for Argon2d hashing
* @param context Pointer to current Argon2 context
* @param hash The password hash to verify. The length of the hash is
* specified by the context outlen member
* @return Zero if successful, a non zero error code otherwise
*/
int argon2d_verify_ctx(argon2_context *context, const char *hash) { int argon2d_verify_ctx(argon2_context *context, const char *hash) {
return argon2_verify_ctx(context, hash, Argon2_d); return argon2_verify_ctx(context, hash, Argon2_d);
} }
/**
* Verify if a given password is correct for Argon2i hashing
* @param context Pointer to current Argon2 context
* @param hash The password hash to verify. The length of the hash is
* specified by the context outlen member
* @return Zero if successful, a non zero error code otherwise
*/
int argon2i_verify_ctx(argon2_context *context, const char *hash) { int argon2i_verify_ctx(argon2_context *context, const char *hash) {
return argon2_verify_ctx(context, hash, Argon2_i); return argon2_verify_ctx(context, hash, Argon2_i);
} }
/**
* Verify if a given password is correct for Argon2id hashing
* @param context Pointer to current Argon2 context
* @param hash The password hash to verify. The length of the hash is
* specified by the context outlen member
* @return Zero if successful, a non zero error code otherwise
*/
int argon2id_verify_ctx(argon2_context *context, const char *hash) { int argon2id_verify_ctx(argon2_context *context, const char *hash) {
return argon2_verify_ctx(context, hash, Argon2_id); return argon2_verify_ctx(context, hash, Argon2_id);
} }
/**
* Get the associated error message for given error code
* @return The error message associated with the given error code
*/
const char *argon2_error_message(int error_code) { const char *argon2_error_message(int error_code) {
switch (error_code) { switch (error_code) {
case ARGON2_OK: case ARGON2_OK:
@ -444,6 +543,16 @@ const char *argon2_error_message(int error_code) {
} }
} }
/**
* Returns the encoded hash length for the given input parameters
* @param t_cost Number of iterations
* @param m_cost Memory usage in kibibytes
* @param parallelism Number of threads; used to compute lanes
* @param saltlen Salt size in bytes
* @param hashlen Hash size in bytes
* @param type The argon2_type that we want the encoded length for
* @return The encoded hash length in bytes
*/
size_t argon2_encodedlen(uint32_t t_cost, uint32_t m_cost, uint32_t parallelism, size_t argon2_encodedlen(uint32_t t_cost, uint32_t m_cost, uint32_t parallelism,
uint32_t saltlen, uint32_t hashlen, argon2_type type) { uint32_t saltlen, uint32_t hashlen, argon2_type type) {
return strlen("$$v=$m=,t=,p=$$") + strlen(argon2_type2string(type, 0)) + return strlen("$$v=$m=,t=,p=$$") + strlen(argon2_type2string(type, 0)) +

View file

@ -1,22 +1,11 @@
#ifndef ARGON2_H #ifndef COSMOPOLITAN_THIRD_PARTY_ARGON2_ARGON2_H_
#define ARGON2_H #define COSMOPOLITAN_THIRD_PARTY_ARGON2_ARGON2_H_
#include "libc/literal.h" #include "libc/literal.h"
COSMOPOLITAN_C_START_
/* clang-format off */
#define ARGON2_NO_THREADS #define ARGON2_NO_THREADS
/* Symbols visibility control */ #if !(__ASSEMBLER__ + __LINKER__ + 0)
#ifdef A2_VISCTL COSMOPOLITAN_C_START_
#define ARGON2_PUBLIC __attribute__((visibility("default")))
#define ARGON2_LOCAL __attribute__ ((visibility ("hidden")))
#elif defined(_MSC_VER)
#define ARGON2_PUBLIC __declspec(dllexport)
#define ARGON2_LOCAL
#else
#define ARGON2_PUBLIC
#define ARGON2_LOCAL
#endif
/* /*
* Argon2 input parameter restrictions * Argon2 input parameter restrictions
@ -42,10 +31,10 @@ COSMOPOLITAN_C_START_
#define ARGON2_MIN(a, b) ((a) < (b) ? (a) : (b)) #define ARGON2_MIN(a, b) ((a) < (b) ? (a) : (b))
/* Max memory size is addressing-space/2, topping at 2^32 blocks (4 TB) */ /* Max memory size is addressing-space/2, topping at 2^32 blocks (4 TB) */
#define ARGON2_MAX_MEMORY_BITS \ #define ARGON2_MAX_MEMORY_BITS \
ARGON2_MIN(UINT32_C(32), (sizeof(void *) * CHAR_BIT - 10 - 1)) 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) ARGON2_MIN(UINT32_C(0xFFFFFFFF), UINT64_C(1) << ARGON2_MAX_MEMORY_BITS)
/* Minimum and maximum number of passes */ /* Minimum and maximum number of passes */
#define ARGON2_MIN_TIME UINT32_C(1) #define ARGON2_MIN_TIME UINT32_C(1)
@ -68,9 +57,9 @@ COSMOPOLITAN_C_START_
#define ARGON2_MAX_SECRET UINT32_C(0xFFFFFFFF) #define ARGON2_MAX_SECRET UINT32_C(0xFFFFFFFF)
/* Flags to determine which fields are securely wiped (default = no wipe). */ /* Flags to determine which fields are securely wiped (default = no wipe). */
#define ARGON2_DEFAULT_FLAGS UINT32_C(0) #define ARGON2_DEFAULT_FLAGS UINT32_C(0)
#define ARGON2_FLAG_CLEAR_PASSWORD (UINT32_C(1) << 0) #define ARGON2_FLAG_CLEAR_PASSWORD (UINT32_C(1) << 0)
#define ARGON2_FLAG_CLEAR_SECRET (UINT32_C(1) << 1) #define ARGON2_FLAG_CLEAR_SECRET (UINT32_C(1) << 1)
/* Global flag to determine if we are wiping internal memory buffers. This flag /* Global flag to determine if we are wiping internal memory buffers. This flag
* is defined in core.c and defaults to 1 (wipe internal memory). */ * is defined in core.c and defaults to 1 (wipe internal memory). */
@ -78,71 +67,48 @@ extern int FLAG_clear_internal_memory;
/* Error codes */ /* Error codes */
typedef enum Argon2_ErrorCodes { typedef enum Argon2_ErrorCodes {
ARGON2_OK = 0, ARGON2_OK = 0,
ARGON2_OUTPUT_PTR_NULL = -1,
ARGON2_OUTPUT_PTR_NULL = -1, ARGON2_OUTPUT_TOO_SHORT = -2,
ARGON2_OUTPUT_TOO_LONG = -3,
ARGON2_OUTPUT_TOO_SHORT = -2, ARGON2_PWD_TOO_SHORT = -4,
ARGON2_OUTPUT_TOO_LONG = -3, ARGON2_PWD_TOO_LONG = -5,
ARGON2_SALT_TOO_SHORT = -6,
ARGON2_PWD_TOO_SHORT = -4, ARGON2_SALT_TOO_LONG = -7,
ARGON2_PWD_TOO_LONG = -5, ARGON2_AD_TOO_SHORT = -8,
ARGON2_AD_TOO_LONG = -9,
ARGON2_SALT_TOO_SHORT = -6, ARGON2_SECRET_TOO_SHORT = -10,
ARGON2_SALT_TOO_LONG = -7, ARGON2_SECRET_TOO_LONG = -11,
ARGON2_TIME_TOO_SMALL = -12,
ARGON2_AD_TOO_SHORT = -8, ARGON2_TIME_TOO_LARGE = -13,
ARGON2_AD_TOO_LONG = -9, ARGON2_MEMORY_TOO_LITTLE = -14,
ARGON2_MEMORY_TOO_MUCH = -15,
ARGON2_SECRET_TOO_SHORT = -10, ARGON2_LANES_TOO_FEW = -16,
ARGON2_SECRET_TOO_LONG = -11, ARGON2_LANES_TOO_MANY = -17,
ARGON2_PWD_PTR_MISMATCH = -18, /* NULL ptr with non-zero length */
ARGON2_TIME_TOO_SMALL = -12, ARGON2_SALT_PTR_MISMATCH = -19, /* NULL ptr with non-zero length */
ARGON2_TIME_TOO_LARGE = -13, ARGON2_SECRET_PTR_MISMATCH = -20, /* NULL ptr with non-zero length */
ARGON2_AD_PTR_MISMATCH = -21, /* NULL ptr with non-zero length */
ARGON2_MEMORY_TOO_LITTLE = -14, ARGON2_MEMORY_ALLOCATION_ERROR = -22,
ARGON2_MEMORY_TOO_MUCH = -15, ARGON2_FREE_MEMORY_CBK_NULL = -23,
ARGON2_ALLOCATE_MEMORY_CBK_NULL = -24,
ARGON2_LANES_TOO_FEW = -16, ARGON2_INCORRECT_PARAMETER = -25,
ARGON2_LANES_TOO_MANY = -17, ARGON2_INCORRECT_TYPE = -26,
ARGON2_OUT_PTR_MISMATCH = -27,
ARGON2_PWD_PTR_MISMATCH = -18, /* NULL ptr with non-zero length */ ARGON2_THREADS_TOO_FEW = -28,
ARGON2_SALT_PTR_MISMATCH = -19, /* NULL ptr with non-zero length */ ARGON2_THREADS_TOO_MANY = -29,
ARGON2_SECRET_PTR_MISMATCH = -20, /* NULL ptr with non-zero length */ ARGON2_MISSING_ARGS = -30,
ARGON2_AD_PTR_MISMATCH = -21, /* NULL ptr with non-zero length */ ARGON2_ENCODING_FAIL = -31,
ARGON2_DECODING_FAIL = -32,
ARGON2_MEMORY_ALLOCATION_ERROR = -22, ARGON2_THREAD_FAIL = -33,
ARGON2_DECODING_LENGTH_FAIL = -34,
ARGON2_FREE_MEMORY_CBK_NULL = -23, ARGON2_VERIFY_MISMATCH = -35
ARGON2_ALLOCATE_MEMORY_CBK_NULL = -24,
ARGON2_INCORRECT_PARAMETER = -25,
ARGON2_INCORRECT_TYPE = -26,
ARGON2_OUT_PTR_MISMATCH = -27,
ARGON2_THREADS_TOO_FEW = -28,
ARGON2_THREADS_TOO_MANY = -29,
ARGON2_MISSING_ARGS = -30,
ARGON2_ENCODING_FAIL = -31,
ARGON2_DECODING_FAIL = -32,
ARGON2_THREAD_FAIL = -33,
ARGON2_DECODING_LENGTH_FAIL = -34,
ARGON2_VERIFY_MISMATCH = -35
} argon2_error_codes; } argon2_error_codes;
/* Memory allocator types --- for external allocation */ /* Memory allocator types --- for external allocation */
typedef int (*allocate_fptr)(uint8_t **memory, size_t bytes_to_allocate); typedef int (*allocate_fptr)(uint8_t **memory, size_t bytes_to_allocate);
typedef void (*deallocate_fptr)(uint8_t *memory, size_t bytes_to_allocate); typedef void (*deallocate_fptr)(uint8_t *memory, size_t bytes_to_allocate);
/* Argon2 external data structures */
/* /*
***** *****
* Context: structure to hold Argon2 inputs: * Context: structure to hold Argon2 inputs:
@ -169,32 +135,24 @@ typedef void (*deallocate_fptr)(uint8_t *memory, size_t bytes_to_allocate);
Argon2_Context(out,8,pwd,32,salt,16,NULL,0,NULL,0,5,1<<20,4,4,NULL,NULL,true,false,false,false) 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 { typedef struct Argon2_Context {
uint8_t *out; /* output array */ uint8_t *out; /* output array */
uint32_t outlen; /* digest length */ uint32_t outlen; /* digest length */
uint8_t *pwd; /* password array */
uint8_t *pwd; /* password array */ uint32_t pwdlen; /* password length */
uint32_t pwdlen; /* password length */ uint8_t *salt; /* salt array */
uint32_t saltlen; /* salt length */
uint8_t *salt; /* salt array */ uint8_t *secret; /* key array */
uint32_t saltlen; /* salt length */ uint32_t secretlen; /* key length */
uint8_t *ad; /* associated data array */
uint8_t *secret; /* key array */ uint32_t adlen; /* associated data length */
uint32_t secretlen; /* key length */ uint32_t t_cost; /* number of passes */
uint32_t m_cost; /* amount of memory requested (KB) */
uint8_t *ad; /* associated data array */ uint32_t lanes; /* number of lanes */
uint32_t adlen; /* associated data length */ uint32_t threads; /* maximum number of threads */
uint32_t version; /* version number */
uint32_t t_cost; /* number of passes */ allocate_fptr allocate_cbk; /* pointer to memory allocator */
uint32_t m_cost; /* amount of memory requested (KB) */ deallocate_fptr free_cbk; /* pointer to memory deallocator */
uint32_t lanes; /* number of lanes */ uint32_t flags; /* array of bool options */
uint32_t threads; /* maximum number of threads */
uint32_t version; /* version number */
allocate_fptr allocate_cbk; /* pointer to memory allocator */
deallocate_fptr free_cbk; /* pointer to memory deallocator */
uint32_t flags; /* array of bool options */
} argon2_context; } argon2_context;
/* Argon2 primitive type */ /* Argon2 primitive type */
@ -206,209 +164,50 @@ typedef enum Argon2_type {
/* Version of the algorithm */ /* Version of the algorithm */
typedef enum Argon2_version { typedef enum Argon2_version {
ARGON2_VERSION_10 = 0x10, ARGON2_VERSION_10 = 0x10,
ARGON2_VERSION_13 = 0x13, ARGON2_VERSION_13 = 0x13,
ARGON2_VERSION_NUMBER = ARGON2_VERSION_13 ARGON2_VERSION_NUMBER = ARGON2_VERSION_13
} argon2_version; } argon2_version;
/* int argon2i_hash_encoded(const uint32_t, const uint32_t, const uint32_t,
* Function that gives the string representation of an argon2_type. const void *, const size_t, const void *, const size_t,
* @param type The argon2_type that we want the string for const size_t, char *, const size_t);
* @param uppercase Whether the string should have the first letter uppercase int argon2i_hash_raw(const uint32_t, const uint32_t, const uint32_t,
* @return NULL if invalid type, otherwise the string representation. const void *, const size_t, const void *, const size_t,
*/ void *, const size_t);
ARGON2_PUBLIC const char *argon2_type2string(argon2_type type, int uppercase); int argon2d_hash_encoded(const uint32_t, const uint32_t, const uint32_t,
const void *, const size_t, const void *, const size_t,
const size_t, char *, const size_t);
int argon2d_hash_raw(const uint32_t, const uint32_t, const uint32_t,
const void *, const size_t, const void *, const size_t,
void *, const size_t);
int argon2id_hash_encoded(const uint32_t, const uint32_t, const uint32_t,
const void *, const size_t, const void *,
const size_t, const size_t, char *, const size_t);
int argon2id_hash_raw(const uint32_t, const uint32_t, const uint32_t,
const void *, const size_t, const void *, const size_t,
void *, const size_t);
int argon2_hash(const uint32_t, const uint32_t, const uint32_t, const void *,
const size_t, const void *, const size_t, void *, const size_t,
char *, const size_t, argon2_type, const uint32_t);
/* const char *argon2_type2string(argon2_type, int);
* Function that performs memory-hard hashing with certain degree of parallelism int argon2_ctx(argon2_context *, argon2_type);
* @param context Pointer to the Argon2 internal structure int argon2i_verify(const char *, const void *, const size_t);
* @return Error code if smth is wrong, ARGON2_OK otherwise int argon2d_verify(const char *, const void *, const size_t);
*/ int argon2id_verify(const char *, const void *, const size_t);
ARGON2_PUBLIC int argon2_ctx(argon2_context *context, argon2_type type); int argon2_verify(const char *, const void *, const size_t, argon2_type);
int argon2d_ctx(argon2_context *);
/** int argon2i_ctx(argon2_context *);
* Hashes a password with Argon2i, producing an encoded hash int argon2id_ctx(argon2_context *);
* @param t_cost Number of iterations int argon2d_verify_ctx(argon2_context *, const char *);
* @param m_cost Sets memory usage to m_cost kibibytes int argon2i_verify_ctx(argon2_context *, const char *);
* @param parallelism Number of threads and compute lanes int argon2id_verify_ctx(argon2_context *, const char *);
* @param pwd Pointer to password int argon2_verify_ctx(argon2_context *, const char *, argon2_type);
* @param pwdlen Password size in bytes const char *argon2_error_message(int);
* @param salt Pointer to salt size_t argon2_encodedlen(uint32_t, uint32_t, uint32_t, uint32_t, uint32_t,
* @param saltlen Salt size in bytes argon2_type);
* @param hashlen Desired length of the hash in bytes
* @param encoded Buffer where to write the encoded hash
* @param encodedlen Size of the buffer (thus max size of the encoded hash)
* @pre Different parallelism levels will give different results
* @pre Returns ARGON2_OK if successful
*/
ARGON2_PUBLIC 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);
/**
* Hashes a password with Argon2i, producing a raw hash at @hash
* @param t_cost Number of iterations
* @param m_cost Sets memory usage to m_cost kibibytes
* @param parallelism Number of threads and compute lanes
* @param pwd Pointer to password
* @param pwdlen Password size in bytes
* @param salt Pointer to salt
* @param saltlen Salt size in bytes
* @param hash Buffer where to write the raw hash - updated by the function
* @param hashlen Desired length of the hash in bytes
* @pre Different parallelism levels will give different results
* @pre Returns ARGON2_OK if successful
*/
ARGON2_PUBLIC 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);
ARGON2_PUBLIC int argon2d_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);
ARGON2_PUBLIC int argon2d_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);
ARGON2_PUBLIC int argon2id_hash_encoded(const uint32_t t_cost,
const uint32_t m_cost,
const uint32_t parallelism,
const void *pwd, const size_t pwdlen,
const void *salt, const size_t saltlen,
const size_t hashlen, char *encoded,
const size_t encodedlen);
ARGON2_PUBLIC int argon2id_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);
/* generic function underlying the above ones */
ARGON2_PUBLIC int argon2_hash(const uint32_t t_cost, const uint32_t m_cost,
const uint32_t parallelism, const void *pwd,
const size_t pwdlen, const void *salt,
const size_t saltlen, void *hash,
const size_t hashlen, char *encoded,
const size_t encodedlen, argon2_type type,
const uint32_t version);
/**
* Verifies a password against an encoded string
* Encoded string is restricted as in validate_inputs()
* @param encoded String encoding parameters, salt, hash
* @param pwd Pointer to password
* @pre Returns ARGON2_OK if successful
*/
ARGON2_PUBLIC int argon2i_verify(const char *encoded, const void *pwd,
const size_t pwdlen);
ARGON2_PUBLIC int argon2d_verify(const char *encoded, const void *pwd,
const size_t pwdlen);
ARGON2_PUBLIC int argon2id_verify(const char *encoded, const void *pwd,
const size_t pwdlen);
/* generic function underlying the above ones */
ARGON2_PUBLIC int argon2_verify(const char *encoded, const void *pwd,
const size_t pwdlen, argon2_type type);
/**
* Argon2d: Version of Argon2 that picks memory blocks depending
* on the password and salt. Only for side-channel-free
* environment!!
*****
* @param context Pointer to current Argon2 context
* @return Zero if successful, a non zero error code otherwise
*/
ARGON2_PUBLIC int argon2d_ctx(argon2_context *context);
/**
* Argon2i: Version of Argon2 that picks memory blocks
* independent on the password and salt. Good for side-channels,
* but worse w.r.t. tradeoff attacks if only one pass is used.
*****
* @param context Pointer to current Argon2 context
* @return Zero if successful, a non zero error code otherwise
*/
ARGON2_PUBLIC int argon2i_ctx(argon2_context *context);
/**
* Argon2id: Version of Argon2 where the first half-pass over memory is
* password-independent, the rest are password-dependent (on the password and
* salt). OK against side channels (they reduce to 1/2-pass Argon2i), and
* better with w.r.t. tradeoff attacks (similar to Argon2d).
*****
* @param context Pointer to current Argon2 context
* @return Zero if successful, a non zero error code otherwise
*/
ARGON2_PUBLIC int argon2id_ctx(argon2_context *context);
/**
* Verify if a given password is correct for Argon2d hashing
* @param context Pointer to current Argon2 context
* @param hash The password hash to verify. The length of the hash is
* specified by the context outlen member
* @return Zero if successful, a non zero error code otherwise
*/
ARGON2_PUBLIC int argon2d_verify_ctx(argon2_context *context, const char *hash);
/**
* Verify if a given password is correct for Argon2i hashing
* @param context Pointer to current Argon2 context
* @param hash The password hash to verify. The length of the hash is
* specified by the context outlen member
* @return Zero if successful, a non zero error code otherwise
*/
ARGON2_PUBLIC int argon2i_verify_ctx(argon2_context *context, const char *hash);
/**
* Verify if a given password is correct for Argon2id hashing
* @param context Pointer to current Argon2 context
* @param hash The password hash to verify. The length of the hash is
* specified by the context outlen member
* @return Zero if successful, a non zero error code otherwise
*/
ARGON2_PUBLIC int argon2id_verify_ctx(argon2_context *context,
const char *hash);
/* generic function underlying the above ones */
ARGON2_PUBLIC int argon2_verify_ctx(argon2_context *context, const char *hash,
argon2_type type);
/**
* Get the associated error message for given error code
* @return The error message associated with the given error code
*/
ARGON2_PUBLIC const char *argon2_error_message(int error_code);
/**
* Returns the encoded hash length for the given input parameters
* @param t_cost Number of iterations
* @param m_cost Memory usage in kibibytes
* @param parallelism Number of threads; used to compute lanes
* @param saltlen Salt size in bytes
* @param hashlen Hash size in bytes
* @param type The argon2_type that we want the encoded length for
* @return The encoded hash length in bytes
*/
ARGON2_PUBLIC size_t argon2_encodedlen(uint32_t t_cost, uint32_t m_cost,
uint32_t parallelism, uint32_t saltlen,
uint32_t hashlen, argon2_type type);
COSMOPOLITAN_C_END_ COSMOPOLITAN_C_END_
#endif #endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
#endif /* COSMOPOLITAN_THIRD_PARTY_ARGON2_ARGON2_H_ */

View file

@ -42,6 +42,11 @@ $(THIRD_PARTY_ARGON2_A).pkg: \
$(THIRD_PARTY_ARGON2_A_OBJS) \ $(THIRD_PARTY_ARGON2_A_OBJS) \
$(foreach x,$(THIRD_PARTY_ARGON2_A_DIRECTDEPS),$($(x)_A).pkg) $(foreach x,$(THIRD_PARTY_ARGON2_A_DIRECTDEPS),$($(x)_A).pkg)
$(THIRD_PARTY_ARGON2_A_OBJS): \
OVERRIDE_CFLAGS += \
-ffunction-sections \
-fdata-sections
THIRD_PARTY_ARGON2_LIBS = $(foreach x,$(THIRD_PARTY_ARGON2_ARTIFACTS),$($(x))) THIRD_PARTY_ARGON2_LIBS = $(foreach x,$(THIRD_PARTY_ARGON2_ARTIFACTS),$($(x)))
THIRD_PARTY_ARGON2_SRCS = $(foreach x,$(THIRD_PARTY_ARGON2_ARTIFACTS),$($(x)_SRCS)) THIRD_PARTY_ARGON2_SRCS = $(foreach x,$(THIRD_PARTY_ARGON2_ARTIFACTS),$($(x)_SRCS))
THIRD_PARTY_ARGON2_HDRS = $(foreach x,$(THIRD_PARTY_ARGON2_ARTIFACTS),$($(x)_HDRS)) THIRD_PARTY_ARGON2_HDRS = $(foreach x,$(THIRD_PARTY_ARGON2_ARTIFACTS),$($(x)_HDRS))

View file

@ -1,66 +1,52 @@
#ifndef PORTABLE_BLAKE2_H #ifndef COSMOPOLITAN_THIRD_PARTY_ARGON2_BLAKE2_H_
#define PORTABLE_BLAKE2_H #define COSMOPOLITAN_THIRD_PARTY_ARGON2_BLAKE2_H_
#include "third_party/argon2/argon2.h" #include "third_party/argon2/argon2.h"
#if !(__ASSEMBLER__ + __LINKER__ + 0)
COSMOPOLITAN_C_START_ COSMOPOLITAN_C_START_
/* clang-format off */
enum blake2b_constant { enum blake2b_constant {
BLAKE2B_BLOCKBYTES = 128, BLAKE2B_BLOCKBYTES = 128,
BLAKE2B_OUTBYTES = 64, BLAKE2B_OUTBYTES = 64,
BLAKE2B_KEYBYTES = 64, BLAKE2B_KEYBYTES = 64,
BLAKE2B_SALTBYTES = 16, BLAKE2B_SALTBYTES = 16,
BLAKE2B_PERSONALBYTES = 16 BLAKE2B_PERSONALBYTES = 16
}; };
#pragma pack(push, 1)
typedef struct __blake2b_param { typedef struct __blake2b_param {
uint8_t digest_length; /* 1 */ uint8_t digest_length; /* 1 */
uint8_t key_length; /* 2 */ uint8_t key_length; /* 2 */
uint8_t fanout; /* 3 */ uint8_t fanout; /* 3 */
uint8_t depth; /* 4 */ uint8_t depth; /* 4 */
uint32_t leaf_length; /* 8 */ uint8_t leaf_length[4]; /* 8 */
uint64_t node_offset; /* 16 */ uint8_t node_offset[8]; /* 16 */
uint8_t node_depth; /* 17 */ uint8_t node_depth; /* 17 */
uint8_t inner_length; /* 18 */ uint8_t inner_length; /* 18 */
uint8_t reserved[14]; /* 32 */ uint8_t reserved[14]; /* 32 */
uint8_t salt[BLAKE2B_SALTBYTES]; /* 48 */ uint8_t salt[BLAKE2B_SALTBYTES]; /* 48 */
uint8_t personal[BLAKE2B_PERSONALBYTES]; /* 64 */ uint8_t personal[BLAKE2B_PERSONALBYTES]; /* 64 */
} blake2b_param; } blake2b_param;
#pragma pack(pop)
typedef struct __blake2b_state { typedef struct __blake2b_state {
uint64_t h[8]; uint64_t h[8];
uint64_t t[2]; uint64_t t[2];
uint64_t f[2]; uint64_t f[2];
uint8_t buf[BLAKE2B_BLOCKBYTES]; uint8_t buf[BLAKE2B_BLOCKBYTES];
unsigned buflen; unsigned buflen;
unsigned outlen; unsigned outlen;
uint8_t last_node; uint8_t last_node;
} blake2b_state; } blake2b_state;
/* Ensure param structs have not been wrongly padded */
/* Poor man's static_assert */
enum {
blake2_size_check_0 = 1 / !!(CHAR_BIT == 8),
blake2_size_check_2 =
1 / !!(sizeof(blake2b_param) == sizeof(uint64_t) * CHAR_BIT)
};
/* Streaming API */ /* Streaming API */
ARGON2_LOCAL int blake2b_init(blake2b_state *S, size_t outlen); int blake2b_init(blake2b_state *, size_t);
ARGON2_LOCAL int blake2b_init_key(blake2b_state *S, size_t outlen, const void *key, int blake2b_init_key(blake2b_state *, size_t, const void *, size_t);
size_t keylen); int blake2b_init_param(blake2b_state *, const blake2b_param *);
ARGON2_LOCAL int blake2b_init_param(blake2b_state *S, const blake2b_param *P); int blake2b_update(blake2b_state *, const void *, size_t);
ARGON2_LOCAL int blake2b_update(blake2b_state *S, const void *in, size_t inlen); int blake2b_final(blake2b_state *, void *, size_t);
ARGON2_LOCAL int blake2b_final(blake2b_state *S, void *out, size_t outlen);
/* Simple API */ /* Simple API */
ARGON2_LOCAL int blake2b(void *out, size_t outlen, const void *in, size_t inlen, int blake2b(void *, size_t, const void *, size_t, const void *, size_t);
const void *key, size_t keylen); int blake2b_long(void *, size_t, const void *, size_t);
/* Argon2 Team - Begin Code */
ARGON2_LOCAL int blake2b_long(void *out, size_t outlen, const void *in, size_t inlen);
/* Argon2 Team - End Code */
COSMOPOLITAN_C_END_ COSMOPOLITAN_C_END_
#endif #endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
#endif /* COSMOPOLITAN_THIRD_PARTY_ARGON2_BLAKE2_H_ */

View file

@ -1,3 +1,20 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:4;tab-width:8;coding:utf-8 -*-│
vi: set net ft=c ts=4 sts=4 sw=4 fenc=utf-8 :vi
Argon2 reference source code package - reference C implementations
Copyright 2015
Daniel Dinu, Dmitry Khovratovich, Jean-Philippe Aumasson, and Samuel Neves
You may use this work under the terms of a Creative Commons CC0 1.0
License/Waiver or the Apache Public License 2.0, at your option. The
terms of these licenses can be found at:
- CC0 1.0 Universal : https://creativecommons.org/publicdomain/zero/1.0 │
- Apache 2.0 : https://www.apache.org/licenses/LICENSE-2.0 │
*/
#include "libc/bits/bits.h" #include "libc/bits/bits.h"
#include "libc/limits.h" #include "libc/limits.h"
#include "third_party/argon2/blake2-impl.h" #include "third_party/argon2/blake2-impl.h"
@ -5,22 +22,18 @@
#include "third_party/argon2/core.h" #include "third_party/argon2/core.h"
/* clang-format off */ /* clang-format off */
/* asm(".ident\t\"\\n\\n\
* Argon2 reference source code package - reference C implementations argon2 (CC0 or Apache2)\\n\
* Copyright 2016 Daniel Dinu, Dmitry Khovratovich\\n\
* Copyright 2015 Copyright 2016 Jean-Philippe Aumasson, Samuel Neves\"");
* Daniel Dinu, Dmitry Khovratovich, Jean-Philippe Aumasson, and Samuel Neves
* /* Ensure param structs have not been wrongly padded */
* You may use this work under the terms of a Creative Commons CC0 1.0 /* Poor man's static_assert */
* License/Waiver or the Apache Public License 2.0, at your option. The terms of enum {
* these licenses can be found at: blake2_size_check_0 = 1 / !!(CHAR_BIT == 8),
* blake2_size_check_2 =
* - CC0 1.0 Universal : https://creativecommons.org/publicdomain/zero/1.0 1 / !!(sizeof(blake2b_param) == sizeof(uint64_t) * CHAR_BIT)
* - Apache 2.0 : https://www.apache.org/licenses/LICENSE-2.0 };
*
* You should have received a copy of both of these licenses along with this
* software. If not, they may be obtained at the above URLs.
*/
static const uint64_t blake2b_IV[8] = { static const uint64_t blake2b_IV[8] = {
UINT64_C(0x6a09e667f3bcc908), UINT64_C(0xbb67ae8584caa73b), UINT64_C(0x6a09e667f3bcc908), UINT64_C(0xbb67ae8584caa73b),
@ -105,8 +118,8 @@ int blake2b_init(blake2b_state *S, size_t outlen) {
P.key_length = 0; P.key_length = 0;
P.fanout = 1; P.fanout = 1;
P.depth = 1; P.depth = 1;
P.leaf_length = 0; WRITE32LE(P.leaf_length, 0);
P.node_offset = 0; WRITE64LE(P.node_offset, 0);
P.node_depth = 0; P.node_depth = 0;
P.inner_length = 0; P.inner_length = 0;
memset(P.reserved, 0, sizeof(P.reserved)); memset(P.reserved, 0, sizeof(P.reserved));
@ -139,8 +152,8 @@ int blake2b_init_key(blake2b_state *S, size_t outlen, const void *key,
P.key_length = (uint8_t)keylen; P.key_length = (uint8_t)keylen;
P.fanout = 1; P.fanout = 1;
P.depth = 1; P.depth = 1;
P.leaf_length = 0; WRITE32LE(P.leaf_length, 0);
P.node_offset = 0; WRITE64LE(P.node_offset, 0);
P.node_depth = 0; P.node_depth = 0;
P.inner_length = 0; P.inner_length = 0;
memset(P.reserved, 0, sizeof(P.reserved)); memset(P.reserved, 0, sizeof(P.reserved));
@ -387,4 +400,3 @@ fail:
return ret; return ret;
#undef TRY #undef TRY
} }
/* Argon2 Team - End Code */

View file

@ -1,27 +1,32 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:4;tab-width:8;coding:utf-8 -*-│
vi: set net ft=c ts=4 sts=4 sw=4 fenc=utf-8 :vi
Argon2 reference source code package - reference C implementations
Copyright 2015
Daniel Dinu, Dmitry Khovratovich, Jean-Philippe Aumasson, and Samuel Neves
You may use this work under the terms of a Creative Commons CC0 1.0
License/Waiver or the Apache Public License 2.0, at your option. The
terms of these licenses can be found at:
- CC0 1.0 Universal : https://creativecommons.org/publicdomain/zero/1.0 │
- Apache 2.0 : https://www.apache.org/licenses/LICENSE-2.0 │
*/
#include "libc/mem/mem.h" #include "libc/mem/mem.h"
#include "third_party/argon2/blake2-impl.h" #include "third_party/argon2/blake2-impl.h"
#include "third_party/argon2/blake2.h" #include "third_party/argon2/blake2.h"
#include "third_party/argon2/core.h" #include "third_party/argon2/core.h"
asm(".ident\t\"\\n\\n\
argon2 (CC0 or Apache2)\\n\
Copyright 2016 Daniel Dinu, Dmitry Khovratovich\\n\
Copyright 2016 Jean-Philippe Aumasson, Samuel Neves\"");
/* clang-format off */ /* clang-format off */
/* int FLAG_clear_internal_memory = 1;
* Argon2 reference source code package - reference C implementations
*
* Copyright 2015
* Daniel Dinu, Dmitry Khovratovich, Jean-Philippe Aumasson, and Samuel Neves
*
* You may use this work under the terms of a Creative Commons CC0 1.0
* License/Waiver or the Apache Public License 2.0, at your option. The terms of
* these licenses can be found at:
*
* - CC0 1.0 Universal : https://creativecommons.org/publicdomain/zero/1.0
* - Apache 2.0 : https://www.apache.org/licenses/LICENSE-2.0
*
* You should have received a copy of both of these licenses along with this
* software. If not, they may be obtained at the above URLs.
*/
/***************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)); memset(b->v, in, sizeof(b->v));
@ -52,34 +57,45 @@ static void store_block(void *output, const block *src) {
} }
} }
/***************Memory functions*****************/ /**
* Allocates memory to the given pointer, uses the appropriate allocator as
* specified in the context. Total allocated memory is num*size.
* @param context argon2_context which specifies the allocator
* @param memory pointer to the pointer to the memory
* @param size the size in bytes for each element to be allocated
* @param num the number of elements to be allocated
* @return ARGON2_OK if @memory is a valid pointer and memory is allocated
*/
int allocate_memory(const argon2_context *context, uint8_t **memory, int allocate_memory(const argon2_context *context, uint8_t **memory,
size_t num, size_t size) { size_t num, size_t size) {
size_t memory_size = num*size; size_t memory_size = num*size;
if (memory == NULL) { if (memory == NULL) {
return ARGON2_MEMORY_ALLOCATION_ERROR; return ARGON2_MEMORY_ALLOCATION_ERROR;
} }
/* 1. Check for multiplication overflow */ /* 1. Check for multiplication overflow */
if (size != 0 && memory_size / size != num) { if (size != 0 && memory_size / size != num) {
return ARGON2_MEMORY_ALLOCATION_ERROR; return ARGON2_MEMORY_ALLOCATION_ERROR;
} }
/* 2. Try to allocate with appropriate allocator */ /* 2. Try to allocate with appropriate allocator */
if (context->allocate_cbk) { if (context->allocate_cbk) {
(context->allocate_cbk)(memory, memory_size); (context->allocate_cbk)(memory, memory_size);
} else { } else {
*memory = malloc(memory_size); *memory = malloc(memory_size);
} }
if (*memory == NULL) { if (*memory == NULL) {
return ARGON2_MEMORY_ALLOCATION_ERROR; return ARGON2_MEMORY_ALLOCATION_ERROR;
} }
return ARGON2_OK; return ARGON2_OK;
} }
/**
* Frees memory at the given pointer, uses the appropriate deallocator as
* specified in the context. Also cleans the memory using clear_internal_memory.
* @param context argon2_context which specifies the deallocator
* @param memory pointer to buffer to be freed
* @param size the size in bytes for each element to be deallocated
* @param num the number of elements to be deallocated
*/
void free_memory(const argon2_context *context, uint8_t *memory, void free_memory(const argon2_context *context, uint8_t *memory,
size_t num, size_t size) { size_t num, size_t size) {
size_t memory_size = num*size; size_t memory_size = num*size;
@ -91,14 +107,31 @@ void free_memory(const argon2_context *context, uint8_t *memory,
} }
} }
/* Memory clear flag defaults to true. */ /**
int FLAG_clear_internal_memory = 1; * Function that securely clears the memory if
* FLAG_clear_internal_memory is set. If the flag isn't set, this
* function does nothing.
*
* @param mem Pointer to the memory
* @param s Memory size in bytes
*/
void clear_internal_memory(void *v, size_t n) { void clear_internal_memory(void *v, size_t n) {
if (FLAG_clear_internal_memory && v) { if (FLAG_clear_internal_memory && v) {
explicit_bzero(v, n); explicit_bzero(v, n);
} }
} }
/**
* XORing the last block of each lane, hashing it, making the tag.
* Deallocates the memory.
*
* @param context current Argon2 context (use only the out parameters from it)
* @param instance Pointer to current instance of Argon2
* @pre instance->state must point to necessary amount of memory
* @pre context->out must point to outlen bytes of memory
* @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) {
if (context != NULL && instance != NULL) { if (context != NULL && instance != NULL) {
block blockhash; block blockhash;
@ -129,6 +162,16 @@ void finalize(const argon2_context *context, argon2_instance_t *instance) {
} }
} }
/**
* Computes absolute position of reference block in the lane following a skewed
* distribution and using a pseudo-random value as input
* @param instance Pointer to the current instance
* @param position Pointer to the current position
* @param pseudo_rand 32-bit pseudo-random value used to determine the position
* @param same_lane Indicates if the block will be taken from the current lane.
* If so we can reference the current segment
* @pre All pointers must be valid
*/
uint32_t index_alpha(const argon2_instance_t *instance, uint32_t index_alpha(const argon2_instance_t *instance,
const argon2_position_t *position, uint32_t pseudo_rand, const argon2_position_t *position, uint32_t pseudo_rand,
int same_lane) { int same_lane) {
@ -309,6 +352,12 @@ fail:
#endif /* ARGON2_NO_THREADS */ #endif /* ARGON2_NO_THREADS */
/**
* 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
* @return ARGON2_OK if successful, @context->state
*/
int fill_memory_blocks(argon2_instance_t *instance) { int fill_memory_blocks(argon2_instance_t *instance) {
if (instance == NULL || instance->lanes == 0) { if (instance == NULL || instance->lanes == 0) {
return ARGON2_INCORRECT_PARAMETER; return ARGON2_INCORRECT_PARAMETER;
@ -321,6 +370,14 @@ int fill_memory_blocks(argon2_instance_t *instance) {
#endif #endif
} }
/**
* Function that validates all inputs against predefined restrictions
* and return an error code.
*
* @param context Pointer to current Argon2 context
* @return ARGON2_OK if everything is all right, otherwise one of error
* codes (all defined in argon.h)
*/
int validate_inputs(const argon2_context *context) { int validate_inputs(const argon2_context *context) {
if (NULL == context) { if (NULL == context) {
return ARGON2_INCORRECT_PARAMETER; return ARGON2_INCORRECT_PARAMETER;
@ -448,6 +505,12 @@ int validate_inputs(const argon2_context *context) {
return ARGON2_OK; return ARGON2_OK;
} }
/**
* Function creates first 2 blocks per lane
* @param instance Pointer to the current instance
* @param blockhash Pointer to the pre-hashing digest
* @pre blockhash must point to @a PREHASH_SEED_LENGTH allocated values
*/
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; uint32_t l;
/* Make the first and second block in each lane as G(H0||0||i) or /* Make the first and second block in each lane as G(H0||0||i) or
@ -471,6 +534,17 @@ void fill_first_blocks(uint8_t *blockhash, const argon2_instance_t *instance) {
clear_internal_memory(blockhash_bytes, ARGON2_BLOCK_SIZE); clear_internal_memory(blockhash_bytes, ARGON2_BLOCK_SIZE);
} }
/**
* Hashes all the inputs into @a blockhash[PREHASH_DIGEST_LENGTH],
* clears password and secret if needed
*
* @param context Pointer to the Argon2 internal structure containing
* memory pointer, and parameters for time and space requirements
* @param blockhash Buffer for pre-hashing digest
* @param type Argon2 type
* @pre @a blockhash must have at least @a PREHASH_DIGEST_LENGTH bytes
* allocated
*/
void initial_hash(uint8_t *blockhash, argon2_context *context, void initial_hash(uint8_t *blockhash, argon2_context *context,
argon2_type type) { argon2_type type) {
blake2b_state BlakeHash; blake2b_state BlakeHash;
@ -545,6 +619,17 @@ void initial_hash(uint8_t *blockhash, argon2_context *context,
blake2b_final(&BlakeHash, blockhash, ARGON2_PREHASH_DIGEST_LENGTH); blake2b_final(&BlakeHash, blockhash, ARGON2_PREHASH_DIGEST_LENGTH);
} }
/**
* Function allocates memory, hashes the inputs with Blake, and creates
* first two blocks. Returns the pointer to the main memory with 2
* blocks per lane initialized.
*
* @param context Pointer to the Argon2 internal structure containing memory
* pointer, and parameters for time and space requirements.
* @param instance Current Argon2 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) {
uint8_t blockhash[ARGON2_PREHASH_SEED_LENGTH]; uint8_t blockhash[ARGON2_PREHASH_SEED_LENGTH];
int result = ARGON2_OK; int result = ARGON2_OK;

View file

@ -1,229 +1,87 @@
/* #ifndef COSMOPOLITAN_THIRD_PARTY_ARGON2_CORE_H_
* Argon2 reference source code package - reference C implementations #define COSMOPOLITAN_THIRD_PARTY_ARGON2_CORE_H_
*
* Copyright 2015
* Daniel Dinu, Dmitry Khovratovich, Jean-Philippe Aumasson, and Samuel Neves
*
* You may use this work under the terms of a Creative Commons CC0 1.0
* License/Waiver or the Apache Public License 2.0, at your option. The terms of
* these licenses can be found at:
*
* - CC0 1.0 Universal : https://creativecommons.org/publicdomain/zero/1.0
* - Apache 2.0 : https://www.apache.org/licenses/LICENSE-2.0
*
* You should have received a copy of both of these licenses along with this
* software. If not, they may be obtained at the above URLs.
*/
#ifndef ARGON2_CORE_H
#define ARGON2_CORE_H
/* clang-format off */
#include "third_party/argon2/argon2.h" #include "third_party/argon2/argon2.h"
#if !(__ASSEMBLER__ + __LINKER__ + 0)
#define CONST_CAST(x) (x)(uintptr_t) COSMOPOLITAN_C_START_
/**********************Argon2 internal constants*******************************/
enum argon2_core_constants { enum argon2_core_constants {
/* Memory block size in bytes */ /* Memory block size in bytes */
ARGON2_BLOCK_SIZE = 1024, ARGON2_BLOCK_SIZE = 1024,
ARGON2_QWORDS_IN_BLOCK = ARGON2_BLOCK_SIZE / 8, ARGON2_QWORDS_IN_BLOCK = ARGON2_BLOCK_SIZE / 8,
ARGON2_OWORDS_IN_BLOCK = ARGON2_BLOCK_SIZE / 16, ARGON2_OWORDS_IN_BLOCK = ARGON2_BLOCK_SIZE / 16,
ARGON2_HWORDS_IN_BLOCK = ARGON2_BLOCK_SIZE / 32, ARGON2_HWORDS_IN_BLOCK = ARGON2_BLOCK_SIZE / 32,
ARGON2_512BIT_WORDS_IN_BLOCK = ARGON2_BLOCK_SIZE / 64, ARGON2_512BIT_WORDS_IN_BLOCK = ARGON2_BLOCK_SIZE / 64,
/* Number of pseudo-random values generated by one call to Blake in
/* Number of pseudo-random values generated by one call to Blake in Argon2i Argon2i to generate reference block positions */
to ARGON2_ADDRESSES_IN_BLOCK = 128,
generate reference block positions */ /* Pre-hashing digest length and its extension*/
ARGON2_ADDRESSES_IN_BLOCK = 128, ARGON2_PREHASH_DIGEST_LENGTH = 64,
ARGON2_PREHASH_SEED_LENGTH = 72
/* Pre-hashing digest length and its extension*/
ARGON2_PREHASH_DIGEST_LENGTH = 64,
ARGON2_PREHASH_SEED_LENGTH = 72
}; };
/*************************Argon2 internal data types***********************/
/* /*
* Structure for the (1KB) memory block implemented as 128 64-bit words. * Structure for the (1KB) memory block implemented as 128 64-bit words.
* Memory blocks can be copied, XORed. Internal words can be accessed by [] (no * Memory blocks can be copied, XORed. Internal words can be accessed by [] (no
* bounds checking). * bounds checking).
*/ */
typedef struct block_ { uint64_t v[ARGON2_QWORDS_IN_BLOCK]; } block; typedef struct block_ {
uint64_t v[ARGON2_QWORDS_IN_BLOCK];
} block;
/*****************Functions that work with the block******************/ void init_block_value(block *, uint8_t);
void copy_block(block *, const block *);
/* Initialize each byte of the block with @in */ void xor_block(block *, const block *);
void init_block_value(block *b, uint8_t in);
/* Copy block @src to block @dst */
void copy_block(block *dst, const block *src);
/* XOR @src onto @dst bytewise */
void xor_block(block *dst, const block *src);
/* /*
* Argon2 instance: memory pointer, number of passes, amount of memory, type, * Argon2 instance: memory pointer, number of passes, amount of memory,
* and derived values. * type, and derived values. Used to evaluate the number and location of
* Used to evaluate the number and location of blocks to construct in each * blocks to construct in each thread.
* thread
*/ */
typedef struct Argon2_instance_t { typedef struct Argon2_instance_t {
block *memory; /* Memory pointer */ block *memory; /* Memory pointer */
uint32_t version; uint32_t version;
uint32_t passes; /* Number of passes */ uint32_t passes; /* Number of passes */
uint32_t memory_blocks; /* Number of blocks in memory */ uint32_t memory_blocks; /* Number of blocks in memory */
uint32_t segment_length; uint32_t segment_length;
uint32_t lane_length; uint32_t lane_length;
uint32_t lanes; uint32_t lanes;
uint32_t threads; uint32_t threads;
argon2_type type; argon2_type type;
int print_internals; /* whether to print the memory blocks */ int print_internals; /* whether to print the memory blocks */
argon2_context *context_ptr; /* points back to original context */ argon2_context *context_ptr; /* points back to original context */
} argon2_instance_t; } argon2_instance_t;
/* /*
* Argon2 position: where we construct the block right now. Used to distribute * Argon2 position: where we construct the block right now. Used to
* work between threads. * distribute work between threads.
*/ */
typedef struct Argon2_position_t { typedef struct Argon2_position_t {
uint32_t pass; uint32_t pass;
uint32_t lane; uint32_t lane;
uint8_t slice; uint8_t slice;
uint32_t index; uint32_t index;
} argon2_position_t; } argon2_position_t;
/*Struct that holds the inputs for thread handling FillSegment*/ /*Struct that holds the inputs for thread handling FillSegment*/
typedef struct Argon2_thread_data { typedef struct Argon2_thread_data {
argon2_instance_t *instance_ptr; argon2_instance_t *instance_ptr;
argon2_position_t pos; argon2_position_t pos;
} argon2_thread_data; } argon2_thread_data;
/*************************Argon2 core functions********************************/ /* argon2 core functions */
int allocate_memory(const argon2_context *, uint8_t **, size_t, size_t);
void free_memory(const argon2_context *, uint8_t *, size_t, size_t);
void clear_internal_memory(void *, size_t);
uint32_t index_alpha(const argon2_instance_t *, const argon2_position_t *,
uint32_t, int);
int validate_inputs(const argon2_context *);
void initial_hash(uint8_t *, argon2_context *, argon2_type);
void fill_first_blocks(uint8_t *, const argon2_instance_t *);
int initialize(argon2_instance_t *, argon2_context *);
void finalize(const argon2_context *, argon2_instance_t *);
void fill_segment(const argon2_instance_t *, argon2_position_t);
int fill_memory_blocks(argon2_instance_t *);
/* Allocates memory to the given pointer, uses the appropriate allocator as COSMOPOLITAN_C_END_
* specified in the context. Total allocated memory is num*size. #endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
* @param context argon2_context which specifies the allocator #endif /* COSMOPOLITAN_THIRD_PARTY_ARGON2_CORE_H_ */
* @param memory pointer to the pointer to the memory
* @param size the size in bytes for each element to be allocated
* @param num the number of elements to be allocated
* @return ARGON2_OK if @memory is a valid pointer and memory is allocated
*/
int allocate_memory(const argon2_context *context, uint8_t **memory,
size_t num, size_t size);
/*
* Frees memory at the given pointer, uses the appropriate deallocator as
* specified in the context. Also cleans the memory using clear_internal_memory.
* @param context argon2_context which specifies the deallocator
* @param memory pointer to buffer to be freed
* @param size the size in bytes for each element to be deallocated
* @param num the number of elements to be deallocated
*/
void free_memory(const argon2_context *context, uint8_t *memory,
size_t num, size_t size);
/* Function that securely cleans the memory. This ignores any flags set
* regarding clearing memory. Usually one just calls clear_internal_memory.
* @param mem Pointer to the memory
* @param s Memory size in bytes
*/
void secure_wipe_memory(void *v, size_t n);
/* Function that securely clears the memory if FLAG_clear_internal_memory is
* set. If the flag isn't set, this function does nothing.
* @param mem Pointer to the memory
* @param s Memory size in bytes
*/
void clear_internal_memory(void *v, size_t n);
/*
* Computes absolute position of reference block in the lane following a skewed
* distribution and using a pseudo-random value as input
* @param instance Pointer to the current instance
* @param position Pointer to the current position
* @param pseudo_rand 32-bit pseudo-random value used to determine the position
* @param same_lane Indicates if the block will be taken from the current lane.
* 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,
int same_lane);
/*
* Function that validates all inputs against predefined restrictions and return
* an error code
* @param context Pointer to current Argon2 context
* @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);
/*
* Hashes all the inputs into @a blockhash[PREHASH_DIGEST_LENGTH], clears
* password and secret if needed
* @param context Pointer to the Argon2 internal structure containing memory
* pointer, and parameters for time and space requirements.
* @param blockhash Buffer for pre-hashing digest
* @param type Argon2 type
* @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);
/*
* Function creates first 2 blocks per lane
* @param instance Pointer to the current instance
* @param blockhash Pointer to the pre-hashing digest
* @pre blockhash must point to @a PREHASH_SEED_LENGTH allocated values
*/
void fill_first_blocks(uint8_t *blockhash, const argon2_instance_t *instance);
/*
* Function allocates memory, hashes the inputs with Blake, and creates first
* two blocks. Returns the pointer to the main memory with 2 blocks per lane
* initialized
* @param context Pointer to the Argon2 internal structure containing memory
* pointer, and parameters for time and space requirements.
* @param instance Current Argon2 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);
/*
* XORing the last block of each lane, hashing it, making the tag. Deallocates
* the memory.
* @param context Pointer to current Argon2 context (use only the out parameters
* from it)
* @param instance Pointer to current instance of Argon2
* @pre instance->state must point to necessary amount of memory
* @pre context->out must point to outlen bytes of memory
* @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);
/*
* Function that fills the segment using previous segments also from other
* threads
* @param context current context
* @param instance Pointer to the current instance
* @param position Current position
* @pre all block pointers must be valid
*/
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
* @return ARGON2_OK if successful, @context->state
*/
int fill_memory_blocks(argon2_instance_t *instance);
#endif

View file

@ -1,26 +1,31 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:4;tab-width:8;coding:utf-8 -*-│
vi: set net ft=c ts=4 sts=4 sw=4 fenc=utf-8 :vi
Argon2 reference source code package - reference C implementations
Copyright 2015
Daniel Dinu, Dmitry Khovratovich, Jean-Philippe Aumasson, and Samuel Neves
You may use this work under the terms of a Creative Commons CC0 1.0
License/Waiver or the Apache Public License 2.0, at your option. The
terms of these licenses can be found at:
- CC0 1.0 Universal : https://creativecommons.org/publicdomain/zero/1.0 │
- Apache 2.0 : https://www.apache.org/licenses/LICENSE-2.0 │
*/
#include "libc/fmt/fmt.h" #include "libc/fmt/fmt.h"
#include "libc/limits.h" #include "libc/limits.h"
#include "libc/str/str.h" #include "libc/str/str.h"
#include "third_party/argon2/core.h" #include "third_party/argon2/core.h"
#include "third_party/argon2/encoding.h" #include "third_party/argon2/encoding.h"
/* clang-format off */
/* asm(".ident\t\"\\n\\n\
* Argon2 reference source code package - reference C implementations argon2 (CC0 or Apache2)\\n\
* Copyright 2016 Daniel Dinu, Dmitry Khovratovich\\n\
* Copyright 2015 Copyright 2016 Jean-Philippe Aumasson, Samuel Neves\"");
* Daniel Dinu, Dmitry Khovratovich, Jean-Philippe Aumasson, and Samuel Neves /* clang-format off */
*
* You may use this work under the terms of a Creative Commons CC0 1.0
* License/Waiver or the Apache Public License 2.0, at your option. The terms of
* these licenses can be found at:
*
* - CC0 1.0 Universal : https://creativecommons.org/publicdomain/zero/1.0
* - Apache 2.0 : https://www.apache.org/licenses/LICENSE-2.0
*
* You should have received a copy of both of these licenses along with this
* software. If not, they may be obtained at the above URLs.
*/
/* /*
* Example code for a decoder and encoder of "hash strings", with Argon2 * Example code for a decoder and encoder of "hash strings", with Argon2
@ -255,6 +260,18 @@ static const char *decode_decimal(const char *str, unsigned long *v) {
* when it is fed into decode_string. * when it is fed into decode_string.
*/ */
/**
* Decodes an Argon2 hash string into the provided structure 'ctx'.
* The only fields that must be set prior to this call are ctx.saltlen and
* ctx.outlen (which must be the maximal salt and out length values that are
* allowed), ctx.salt and ctx.out (which must be buffers of the specified
* length), and ctx.pwd and ctx.pwdlen which must hold a valid password.
*
* Invalid input string causes an error. On success, the ctx is valid and all
* fields have been initialized.
*
* @return value is ARGON2_OK on success, other ARGON2_ codes on error
*/
int decode_string(argon2_context *ctx, const char *str, argon2_type type) { int decode_string(argon2_context *ctx, const char *str, argon2_type type) {
/* check for prefix */ /* check for prefix */
@ -370,6 +387,14 @@ int decode_string(argon2_context *ctx, const char *str, argon2_type type) {
#undef BIN #undef BIN
} }
/**
* Encodes an Argon2 hash string into the provided buffer. 'dst_len'
* contains the size, in characters, of the 'dst' buffer; if 'dst_len'
* is less than the number of required characters (including the
* terminating 0), then this function returns ARGON2_ENCODING_ERROR.
*
* @return on success, ARGON2_OK is returned
*/
int encode_string(char *dst, size_t dst_len, argon2_context *ctx, int encode_string(char *dst, size_t dst_len, argon2_context *ctx,
argon2_type type) { argon2_type type) {
#define SS(str) \ #define SS(str) \
@ -437,9 +462,9 @@ int encode_string(char *dst, size_t dst_len, argon2_context *ctx,
#undef SB #undef SB
} }
/** Returns length of the encoded byte stream with length len */
size_t b64len(uint32_t len) { size_t b64len(uint32_t len) {
size_t olen = ((size_t)len / 3) << 2; size_t olen = ((size_t)len / 3) << 2;
switch (len % 3) { switch (len % 3) {
case 2: case 2:
olen++; olen++;
@ -448,10 +473,10 @@ size_t b64len(uint32_t len) {
olen += 2; olen += 2;
break; break;
} }
return olen; return olen;
} }
/** Returns length of the encoded number num */
size_t numlen(uint32_t num) { size_t numlen(uint32_t num) {
size_t len = 1; size_t len = 1;
while (num >= 10) { while (num >= 10) {

View file

@ -1,58 +1,18 @@
/* #ifndef COSMOPOLITAN_THIRD_PARTY_ARGON2_ENCODING_H_
* Argon2 reference source code package - reference C implementations #define COSMOPOLITAN_THIRD_PARTY_ARGON2_ENCODING_H_
*
* Copyright 2015
* Daniel Dinu, Dmitry Khovratovich, Jean-Philippe Aumasson, and Samuel Neves
*
* You may use this work under the terms of a Creative Commons CC0 1.0
* License/Waiver or the Apache Public License 2.0, at your option. The terms of
* these licenses can be found at:
*
* - CC0 1.0 Universal : https://creativecommons.org/publicdomain/zero/1.0
* - Apache 2.0 : https://www.apache.org/licenses/LICENSE-2.0
*
* You should have received a copy of both of these licenses along with this
* software. If not, they may be obtained at the above URLs.
*/
#ifndef ENCODING_H
#define ENCODING_H
#include "third_party/argon2/argon2.h" #include "third_party/argon2/argon2.h"
/* clang-format off */ #if !(__ASSEMBLER__ + __LINKER__ + 0)
COSMOPOLITAN_C_START_
#define ARGON2_MAX_DECODED_LANES UINT32_C(255) #define ARGON2_MAX_DECODED_LANES UINT32_C(255)
#define ARGON2_MIN_DECODED_SALT_LEN UINT32_C(8) #define ARGON2_MIN_DECODED_SALT_LEN UINT32_C(8)
#define ARGON2_MIN_DECODED_OUT_LEN UINT32_C(12) #define ARGON2_MIN_DECODED_OUT_LEN UINT32_C(12)
/* int encode_string(char *, size_t, argon2_context *, argon2_type);
* encode an Argon2 hash string into the provided buffer. 'dst_len' int decode_string(argon2_context *, const char *, argon2_type);
* contains the size, in characters, of the 'dst' buffer; if 'dst_len' size_t b64len(uint32_t);
* is less than the number of required characters (including the size_t numlen(uint32_t);
* terminating 0), then this function returns ARGON2_ENCODING_ERROR.
*
* on success, ARGON2_OK is returned.
*/
int encode_string(char *dst, size_t dst_len, argon2_context *ctx,
argon2_type type);
/* COSMOPOLITAN_C_END_
* Decodes an Argon2 hash string into the provided structure 'ctx'. #endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
* The only fields that must be set prior to this call are ctx.saltlen and #endif /* COSMOPOLITAN_THIRD_PARTY_ARGON2_ENCODING_H_ */
* ctx.outlen (which must be the maximal salt and out length values that are
* allowed), ctx.salt and ctx.out (which must be buffers of the specified
* length), and ctx.pwd and ctx.pwdlen which must hold a valid password.
*
* Invalid input string causes an error. On success, the ctx is valid and all
* fields have been initialized.
*
* Returned value is ARGON2_OK on success, other ARGON2_ codes on error.
*/
int decode_string(argon2_context *ctx, const char *str, argon2_type type);
/* Returns the length of the encoded byte stream with length len */
size_t b64len(uint32_t len);
/* Returns the length of the encoded number num */
size_t numlen(uint32_t num);
#endif

View file

@ -1,9 +1,31 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:4;tab-width:8;coding:utf-8 -*-│
vi: set net ft=c ts=4 sts=4 sw=4 fenc=utf-8 :vi
Argon2 reference source code package - reference C implementations
Copyright 2015
Daniel Dinu, Dmitry Khovratovich, Jean-Philippe Aumasson, and Samuel Neves
You may use this work under the terms of a Creative Commons CC0 1.0
License/Waiver or the Apache Public License 2.0, at your option. The
terms of these licenses can be found at:
- CC0 1.0 Universal : https://creativecommons.org/publicdomain/zero/1.0 │
- Apache 2.0 : https://www.apache.org/licenses/LICENSE-2.0 │
*/
#include "libc/log/libfatal.internal.h" #include "libc/log/libfatal.internal.h"
#include "third_party/argon2/argon2.h" #include "third_party/argon2/argon2.h"
#include "third_party/argon2/blake2-impl.h" #include "third_party/argon2/blake2-impl.h"
#include "third_party/argon2/blake2.h" #include "third_party/argon2/blake2.h"
#include "third_party/argon2/blamka-round-ref.h" #include "third_party/argon2/blamka-round-ref.h"
#include "third_party/argon2/core.h" #include "third_party/argon2/core.h"
asm(".ident\t\"\\n\\n\
argon2 (CC0 or Apache2)\\n\
Copyright 2016 Daniel Dinu, Dmitry Khovratovich\\n\
Copyright 2016 Jean-Philippe Aumasson, Samuel Neves\"");
/* clang-format off */ /* clang-format off */
/* /*
@ -85,6 +107,15 @@ static void next_addresses(block *address_block, block *input_block,
fill_block(zero_block, address_block, address_block, 0); fill_block(zero_block, address_block, address_block, 0);
} }
/**
* Function that fills the segment using previous segments also from
* other threads.
*
* @param context current context
* @param instance Pointer to the current instance
* @param position Current position
* @pre all block pointers must be valid
*/
void fill_segment(const argon2_instance_t *instance, void fill_segment(const argon2_instance_t *instance,
argon2_position_t position) { argon2_position_t position) {
block *ref_block = NULL, *curr_block = NULL; block *ref_block = NULL, *curr_block = NULL;

View file

@ -1,8 +1,49 @@
/*-*- mode:c;indent-tabs-mode:t;c-basic-offset:8;tab-width:8;coding:utf-8 -*-│
vi: set et ft=c ts=8 tw=8 fenc=utf-8 :vi
largon2
Copyright © 2016 Thibault Charbonnier
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include "libc/isystem/stdio.h"
#include "libc/isystem/string.h"
#include "third_party/argon2/argon2.h"
#include "third_party/lua/lauxlib.h"
#include "third_party/lua/lua.h"
#include "third_party/lua/lualib.h"
asm(".ident\t\"\\n\\n\
largon2 (MIT License)\\n\
Copyright 2016 Thibault Charbonnier\"");
asm(".include \"libc/disclaimer.inc\"");
// clang-format off
/*** /***
Lua C binding for the Argon2 password hashing function. Compatible with Lua Lua C binding for the Argon2 password hashing function.
5.x and LuaJIT. Compatible with Lua 5.x and LuaJIT.
See the [Argon2 documentation](https://github.com/P-H-C/phc-winner-argon2) for
in-depth instructions and details about Argon2. See the [Argon2 documentation](https://github.com/P-H-C/phc-winner-argon2)
for in-depth instructions and details about Argon2.
This module's version is compatible with Argon2 This module's version is compatible with Argon2
[20161029](https://github.com/P-H-C/phc-winner-argon2/releases/tag/20161029) [20161029](https://github.com/P-H-C/phc-winner-argon2/releases/tag/20161029)
@ -19,15 +60,6 @@ original implementaiton.
@release 3.0.1 @release 3.0.1
*/ */
#include <libc/isystem/string.h>
#include <libc/isystem/stdio.h>
#include <third_party/argon2/argon2.h>
#include <third_party/lua/lauxlib.h>
#include <third_party/lua/lua.h>
#include <third_party/lua/lualib.h>
#ifndef LUA_51 #ifndef LUA_51
#if !defined(LUA_VERSION_NUM) || LUA_VERSION_NUM < 502 #if !defined(LUA_VERSION_NUM) || LUA_VERSION_NUM < 502
#define LUA_51 1 #define LUA_51 1