From 4881ae752759efc4a2ba3ab0a65a7b0a162d82d6 Mon Sep 17 00:00:00 2001 From: Justine Tunney Date: Mon, 21 Mar 2022 07:25:48 -0700 Subject: [PATCH] Update Argon2 for style - Make sure notice licenses are embedded - Remove copyright and docs from headers --- third_party/argon2/argon2.c | 151 +++++++++++-- third_party/argon2/argon2.h | 413 +++++++++------------------------- third_party/argon2/argon2.mk | 5 + third_party/argon2/blake2.h | 84 +++---- third_party/argon2/blake2b.c | 54 +++-- third_party/argon2/core.c | 137 ++++++++--- third_party/argon2/core.h | 262 +++++---------------- third_party/argon2/encoding.c | 63 ++++-- third_party/argon2/encoding.h | 66 ++---- third_party/argon2/ref.c | 31 +++ tool/net/largon2.c | 58 +++-- 11 files changed, 613 insertions(+), 711 deletions(-) diff --git a/third_party/argon2/argon2.c b/third_party/argon2/argon2.c index 6fa853c39..8c876c7b5 100644 --- a/third_party/argon2/argon2.c +++ b/third_party/argon2/argon2.c @@ -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/mem/mem.h" #include "libc/str/str.h" #include "third_party/argon2/argon2.h" #include "third_party/argon2/core.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 */ -/* - * 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. +/** + * Function that gives the string representation of an argon2_type. + * @param type The argon2_type that we want the string for + * @param uppercase Whether the string should have the first letter uppercase + * @return NULL if invalid type, otherwise the string representation. */ - const char *argon2_type2string(argon2_type type, int uppercase) { switch (type) { case Argon2_d: @@ -32,10 +43,14 @@ const char *argon2_type2string(argon2_type type, int uppercase) { case Argon2_id: return uppercase ? "Argon2id" : "argon2id"; } - 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) { /* 1. Validate all inputs */ 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.outlen = (uint32_t)hashlen; - context.pwd = CONST_CAST(uint8_t *)pwd; + context.pwd = (uint8_t *)(uintptr_t)pwd; 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.secret = NULL; context.secretlen = 0; @@ -176,6 +191,21 @@ int argon2_hash(const uint32_t t_cost, const uint32_t m_cost, 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, const uint32_t parallelism, const void *pwd, 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); } +/** + * 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, const uint32_t parallelism, const void *pwd, 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; uint8_t *desired_result = NULL; - int ret = ARGON2_OK; - size_t encoded_len; uint32_t max_field_len; @@ -312,6 +354,13 @@ fail: 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) { 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); } +/** + * 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) { 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) { 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) { return argon2_ctx(context, Argon2_id); } @@ -353,18 +427,43 @@ int argon2_verify_ctx(argon2_context *context, const char *hash, 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) { 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) { 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) { 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) { switch (error_code) { 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, uint32_t saltlen, uint32_t hashlen, argon2_type type) { return strlen("$$v=$m=,t=,p=$$") + strlen(argon2_type2string(type, 0)) + diff --git a/third_party/argon2/argon2.h b/third_party/argon2/argon2.h index 91d3093ba..c65efabce 100644 --- a/third_party/argon2/argon2.h +++ b/third_party/argon2/argon2.h @@ -1,22 +1,11 @@ -#ifndef ARGON2_H -#define ARGON2_H +#ifndef COSMOPOLITAN_THIRD_PARTY_ARGON2_ARGON2_H_ +#define COSMOPOLITAN_THIRD_PARTY_ARGON2_ARGON2_H_ #include "libc/literal.h" -COSMOPOLITAN_C_START_ -/* clang-format off */ #define ARGON2_NO_THREADS -/* Symbols visibility control */ -#ifdef A2_VISCTL -#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 +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ /* * Argon2 input parameter restrictions @@ -42,10 +31,10 @@ COSMOPOLITAN_C_START_ #define ARGON2_MIN(a, b) ((a) < (b) ? (a) : (b)) /* Max memory size is addressing-space/2, 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 \ - ARGON2_MIN(UINT32_C(0xFFFFFFFF), UINT64_C(1) << ARGON2_MAX_MEMORY_BITS) +#define ARGON2_MAX_MEMORY_BITS \ + ARGON2_MIN(UINT32_C(32), (sizeof(void *) * CHAR_BIT - 10 - 1)) +#define ARGON2_MAX_MEMORY \ + ARGON2_MIN(UINT32_C(0xFFFFFFFF), UINT64_C(1) << ARGON2_MAX_MEMORY_BITS) /* Minimum and maximum number of passes */ #define ARGON2_MIN_TIME UINT32_C(1) @@ -68,9 +57,9 @@ COSMOPOLITAN_C_START_ #define ARGON2_MAX_SECRET UINT32_C(0xFFFFFFFF) /* 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_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 * is defined in core.c and defaults to 1 (wipe internal memory). */ @@ -78,71 +67,48 @@ extern int FLAG_clear_internal_memory; /* Error codes */ typedef enum Argon2_ErrorCodes { - ARGON2_OK = 0, - - ARGON2_OUTPUT_PTR_NULL = -1, - - ARGON2_OUTPUT_TOO_SHORT = -2, - ARGON2_OUTPUT_TOO_LONG = -3, - - ARGON2_PWD_TOO_SHORT = -4, - ARGON2_PWD_TOO_LONG = -5, - - ARGON2_SALT_TOO_SHORT = -6, - ARGON2_SALT_TOO_LONG = -7, - - ARGON2_AD_TOO_SHORT = -8, - ARGON2_AD_TOO_LONG = -9, - - ARGON2_SECRET_TOO_SHORT = -10, - 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_LANES_TOO_FEW = -16, - ARGON2_LANES_TOO_MANY = -17, - - ARGON2_PWD_PTR_MISMATCH = -18, /* NULL ptr with non-zero length */ - ARGON2_SALT_PTR_MISMATCH = -19, /* NULL ptr with non-zero length */ - ARGON2_SECRET_PTR_MISMATCH = -20, /* NULL ptr with non-zero length */ - ARGON2_AD_PTR_MISMATCH = -21, /* NULL ptr with non-zero length */ - - ARGON2_MEMORY_ALLOCATION_ERROR = -22, - - ARGON2_FREE_MEMORY_CBK_NULL = -23, - 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_OK = 0, + ARGON2_OUTPUT_PTR_NULL = -1, + ARGON2_OUTPUT_TOO_SHORT = -2, + ARGON2_OUTPUT_TOO_LONG = -3, + ARGON2_PWD_TOO_SHORT = -4, + ARGON2_PWD_TOO_LONG = -5, + ARGON2_SALT_TOO_SHORT = -6, + ARGON2_SALT_TOO_LONG = -7, + ARGON2_AD_TOO_SHORT = -8, + ARGON2_AD_TOO_LONG = -9, + ARGON2_SECRET_TOO_SHORT = -10, + 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_LANES_TOO_FEW = -16, + ARGON2_LANES_TOO_MANY = -17, + ARGON2_PWD_PTR_MISMATCH = -18, /* NULL ptr with non-zero length */ + ARGON2_SALT_PTR_MISMATCH = -19, /* NULL ptr with non-zero length */ + ARGON2_SECRET_PTR_MISMATCH = -20, /* NULL ptr with non-zero length */ + ARGON2_AD_PTR_MISMATCH = -21, /* NULL ptr with non-zero length */ + ARGON2_MEMORY_ALLOCATION_ERROR = -22, + ARGON2_FREE_MEMORY_CBK_NULL = -23, + 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; /* Memory allocator types --- for external allocation */ typedef int (*allocate_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: @@ -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) */ typedef struct Argon2_Context { - uint8_t *out; /* output array */ - uint32_t outlen; /* digest length */ - - uint8_t *pwd; /* password array */ - uint32_t pwdlen; /* password length */ - - uint8_t *salt; /* salt array */ - uint32_t saltlen; /* salt length */ - - uint8_t *secret; /* key array */ - uint32_t secretlen; /* key length */ - - uint8_t *ad; /* associated data array */ - uint32_t adlen; /* associated data length */ - - uint32_t t_cost; /* number of passes */ - uint32_t m_cost; /* amount of memory requested (KB) */ - uint32_t lanes; /* number of lanes */ - uint32_t threads; /* maximum number of threads */ - - uint32_t 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 */ + uint8_t *out; /* output array */ + uint32_t outlen; /* digest length */ + uint8_t *pwd; /* password array */ + uint32_t pwdlen; /* password length */ + uint8_t *salt; /* salt array */ + uint32_t saltlen; /* salt length */ + uint8_t *secret; /* key array */ + uint32_t secretlen; /* key length */ + uint8_t *ad; /* associated data array */ + uint32_t adlen; /* associated data length */ + uint32_t t_cost; /* number of passes */ + uint32_t m_cost; /* amount of memory requested (KB) */ + uint32_t lanes; /* number of lanes */ + uint32_t threads; /* maximum number of threads */ + uint32_t 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 primitive type */ @@ -206,209 +164,50 @@ typedef enum Argon2_type { /* Version of the algorithm */ typedef enum Argon2_version { - ARGON2_VERSION_10 = 0x10, - ARGON2_VERSION_13 = 0x13, - ARGON2_VERSION_NUMBER = ARGON2_VERSION_13 + ARGON2_VERSION_10 = 0x10, + ARGON2_VERSION_13 = 0x13, + ARGON2_VERSION_NUMBER = ARGON2_VERSION_13 } argon2_version; -/* - * Function that gives the string representation of an argon2_type. - * @param type The argon2_type that we want the string for - * @param uppercase Whether the string should have the first letter uppercase - * @return NULL if invalid type, otherwise the string representation. - */ -ARGON2_PUBLIC const char *argon2_type2string(argon2_type type, int uppercase); +int argon2i_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 argon2i_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 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); -/* - * 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 - */ -ARGON2_PUBLIC int argon2_ctx(argon2_context *context, argon2_type type); - -/** - * 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 - */ -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); +const char *argon2_type2string(argon2_type, int); +int argon2_ctx(argon2_context *, argon2_type); +int argon2i_verify(const char *, const void *, const size_t); +int argon2d_verify(const char *, const void *, const size_t); +int argon2id_verify(const char *, const void *, const size_t); +int argon2_verify(const char *, const void *, const size_t, argon2_type); +int argon2d_ctx(argon2_context *); +int argon2i_ctx(argon2_context *); +int argon2id_ctx(argon2_context *); +int argon2d_verify_ctx(argon2_context *, const char *); +int argon2i_verify_ctx(argon2_context *, const char *); +int argon2id_verify_ctx(argon2_context *, const char *); +int argon2_verify_ctx(argon2_context *, const char *, argon2_type); +const char *argon2_error_message(int); +size_t argon2_encodedlen(uint32_t, uint32_t, uint32_t, uint32_t, uint32_t, + argon2_type); COSMOPOLITAN_C_END_ -#endif +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_THIRD_PARTY_ARGON2_ARGON2_H_ */ diff --git a/third_party/argon2/argon2.mk b/third_party/argon2/argon2.mk index 03a805c74..9599effd0 100644 --- a/third_party/argon2/argon2.mk +++ b/third_party/argon2/argon2.mk @@ -42,6 +42,11 @@ $(THIRD_PARTY_ARGON2_A).pkg: \ $(THIRD_PARTY_ARGON2_A_OBJS) \ $(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_SRCS = $(foreach x,$(THIRD_PARTY_ARGON2_ARTIFACTS),$($(x)_SRCS)) THIRD_PARTY_ARGON2_HDRS = $(foreach x,$(THIRD_PARTY_ARGON2_ARTIFACTS),$($(x)_HDRS)) diff --git a/third_party/argon2/blake2.h b/third_party/argon2/blake2.h index 50ea43dca..ca21dfae0 100644 --- a/third_party/argon2/blake2.h +++ b/third_party/argon2/blake2.h @@ -1,66 +1,52 @@ -#ifndef PORTABLE_BLAKE2_H -#define PORTABLE_BLAKE2_H +#ifndef COSMOPOLITAN_THIRD_PARTY_ARGON2_BLAKE2_H_ +#define COSMOPOLITAN_THIRD_PARTY_ARGON2_BLAKE2_H_ #include "third_party/argon2/argon2.h" +#if !(__ASSEMBLER__ + __LINKER__ + 0) COSMOPOLITAN_C_START_ -/* clang-format off */ enum blake2b_constant { - BLAKE2B_BLOCKBYTES = 128, - BLAKE2B_OUTBYTES = 64, - BLAKE2B_KEYBYTES = 64, - BLAKE2B_SALTBYTES = 16, - BLAKE2B_PERSONALBYTES = 16 + BLAKE2B_BLOCKBYTES = 128, + BLAKE2B_OUTBYTES = 64, + BLAKE2B_KEYBYTES = 64, + BLAKE2B_SALTBYTES = 16, + BLAKE2B_PERSONALBYTES = 16 }; -#pragma pack(push, 1) typedef struct __blake2b_param { - uint8_t digest_length; /* 1 */ - uint8_t key_length; /* 2 */ - uint8_t fanout; /* 3 */ - uint8_t depth; /* 4 */ - uint32_t leaf_length; /* 8 */ - uint64_t node_offset; /* 16 */ - uint8_t node_depth; /* 17 */ - uint8_t inner_length; /* 18 */ - uint8_t reserved[14]; /* 32 */ - uint8_t salt[BLAKE2B_SALTBYTES]; /* 48 */ - uint8_t personal[BLAKE2B_PERSONALBYTES]; /* 64 */ + uint8_t digest_length; /* 1 */ + uint8_t key_length; /* 2 */ + uint8_t fanout; /* 3 */ + uint8_t depth; /* 4 */ + uint8_t leaf_length[4]; /* 8 */ + uint8_t node_offset[8]; /* 16 */ + uint8_t node_depth; /* 17 */ + uint8_t inner_length; /* 18 */ + uint8_t reserved[14]; /* 32 */ + uint8_t salt[BLAKE2B_SALTBYTES]; /* 48 */ + uint8_t personal[BLAKE2B_PERSONALBYTES]; /* 64 */ } blake2b_param; -#pragma pack(pop) typedef struct __blake2b_state { - uint64_t h[8]; - uint64_t t[2]; - uint64_t f[2]; - uint8_t buf[BLAKE2B_BLOCKBYTES]; - unsigned buflen; - unsigned outlen; - uint8_t last_node; + uint64_t h[8]; + uint64_t t[2]; + uint64_t f[2]; + uint8_t buf[BLAKE2B_BLOCKBYTES]; + unsigned buflen; + unsigned outlen; + uint8_t last_node; } 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 */ -ARGON2_LOCAL int blake2b_init(blake2b_state *S, size_t outlen); -ARGON2_LOCAL int blake2b_init_key(blake2b_state *S, size_t outlen, const void *key, - size_t keylen); -ARGON2_LOCAL int blake2b_init_param(blake2b_state *S, const blake2b_param *P); -ARGON2_LOCAL int blake2b_update(blake2b_state *S, const void *in, size_t inlen); -ARGON2_LOCAL int blake2b_final(blake2b_state *S, void *out, size_t outlen); +int blake2b_init(blake2b_state *, size_t); +int blake2b_init_key(blake2b_state *, size_t, const void *, size_t); +int blake2b_init_param(blake2b_state *, const blake2b_param *); +int blake2b_update(blake2b_state *, const void *, size_t); +int blake2b_final(blake2b_state *, void *, size_t); /* Simple API */ -ARGON2_LOCAL int blake2b(void *out, size_t outlen, const void *in, size_t inlen, - const void *key, size_t keylen); - -/* Argon2 Team - Begin Code */ -ARGON2_LOCAL int blake2b_long(void *out, size_t outlen, const void *in, size_t inlen); -/* Argon2 Team - End Code */ +int blake2b(void *, size_t, const void *, size_t, const void *, size_t); +int blake2b_long(void *, size_t, const void *, size_t); COSMOPOLITAN_C_END_ -#endif +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_THIRD_PARTY_ARGON2_BLAKE2_H_ */ diff --git a/third_party/argon2/blake2b.c b/third_party/argon2/blake2b.c index 733833d60..89ec078ab 100644 --- a/third_party/argon2/blake2b.c +++ b/third_party/argon2/blake2b.c @@ -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/limits.h" #include "third_party/argon2/blake2-impl.h" @@ -5,22 +22,18 @@ #include "third_party/argon2/core.h" /* clang-format off */ -/* - * 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. - */ +asm(".ident\t\"\\n\\n\ +argon2 (CC0 or Apache2)\\n\ +Copyright 2016 Daniel Dinu, Dmitry Khovratovich\\n\ +Copyright 2016 Jean-Philippe Aumasson, Samuel Neves\""); + +/* 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) +}; static const uint64_t blake2b_IV[8] = { UINT64_C(0x6a09e667f3bcc908), UINT64_C(0xbb67ae8584caa73b), @@ -105,8 +118,8 @@ int blake2b_init(blake2b_state *S, size_t outlen) { P.key_length = 0; P.fanout = 1; P.depth = 1; - P.leaf_length = 0; - P.node_offset = 0; + WRITE32LE(P.leaf_length, 0); + WRITE64LE(P.node_offset, 0); P.node_depth = 0; P.inner_length = 0; 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.fanout = 1; P.depth = 1; - P.leaf_length = 0; - P.node_offset = 0; + WRITE32LE(P.leaf_length, 0); + WRITE64LE(P.node_offset, 0); P.node_depth = 0; P.inner_length = 0; memset(P.reserved, 0, sizeof(P.reserved)); @@ -387,4 +400,3 @@ fail: return ret; #undef TRY } -/* Argon2 Team - End Code */ diff --git a/third_party/argon2/core.c b/third_party/argon2/core.c index a69409306..8befb8ad2 100644 --- a/third_party/argon2/core.c +++ b/third_party/argon2/core.c @@ -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 "third_party/argon2/blake2-impl.h" #include "third_party/argon2/blake2.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 */ -/* - * 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**********/ +int FLAG_clear_internal_memory = 1; void init_block_value(block *b, uint8_t in) { 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, size_t num, size_t size) { size_t memory_size = num*size; if (memory == NULL) { return ARGON2_MEMORY_ALLOCATION_ERROR; } - /* 1. Check for multiplication overflow */ if (size != 0 && memory_size / size != num) { return ARGON2_MEMORY_ALLOCATION_ERROR; } - /* 2. Try to allocate with appropriate allocator */ if (context->allocate_cbk) { (context->allocate_cbk)(memory, memory_size); } else { *memory = malloc(memory_size); } - if (*memory == NULL) { return ARGON2_MEMORY_ALLOCATION_ERROR; } - 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, size_t num, size_t 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) { if (FLAG_clear_internal_memory && v) { 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) { if (context != NULL && instance != NULL) { 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, const argon2_position_t *position, uint32_t pseudo_rand, int same_lane) { @@ -309,6 +352,12 @@ fail: #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) { if (instance == NULL || instance->lanes == 0) { return ARGON2_INCORRECT_PARAMETER; @@ -321,6 +370,14 @@ int fill_memory_blocks(argon2_instance_t *instance) { #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) { if (NULL == context) { return ARGON2_INCORRECT_PARAMETER; @@ -448,6 +505,12 @@ int validate_inputs(const argon2_context *context) { 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) { uint32_t l; /* 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); } +/** + * 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) { blake2b_state BlakeHash; @@ -545,6 +619,17 @@ void initial_hash(uint8_t *blockhash, argon2_context *context, 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) { uint8_t blockhash[ARGON2_PREHASH_SEED_LENGTH]; int result = ARGON2_OK; diff --git a/third_party/argon2/core.h b/third_party/argon2/core.h index a34c0f94f..7cdfc54e6 100644 --- a/third_party/argon2/core.h +++ b/third_party/argon2/core.h @@ -1,229 +1,87 @@ -/* - * 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. - */ - -#ifndef ARGON2_CORE_H -#define ARGON2_CORE_H -/* clang-format off */ - +#ifndef COSMOPOLITAN_THIRD_PARTY_ARGON2_CORE_H_ +#define COSMOPOLITAN_THIRD_PARTY_ARGON2_CORE_H_ #include "third_party/argon2/argon2.h" - -#define CONST_CAST(x) (x)(uintptr_t) - -/**********************Argon2 internal constants*******************************/ +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ enum argon2_core_constants { - /* Memory block size in bytes */ - ARGON2_BLOCK_SIZE = 1024, - ARGON2_QWORDS_IN_BLOCK = ARGON2_BLOCK_SIZE / 8, - ARGON2_OWORDS_IN_BLOCK = ARGON2_BLOCK_SIZE / 16, - ARGON2_HWORDS_IN_BLOCK = ARGON2_BLOCK_SIZE / 32, - ARGON2_512BIT_WORDS_IN_BLOCK = ARGON2_BLOCK_SIZE / 64, - - /* Number of pseudo-random values generated by one call to Blake in Argon2i - to - generate reference block positions */ - ARGON2_ADDRESSES_IN_BLOCK = 128, - - /* Pre-hashing digest length and its extension*/ - ARGON2_PREHASH_DIGEST_LENGTH = 64, - ARGON2_PREHASH_SEED_LENGTH = 72 + /* Memory block size in bytes */ + ARGON2_BLOCK_SIZE = 1024, + ARGON2_QWORDS_IN_BLOCK = ARGON2_BLOCK_SIZE / 8, + ARGON2_OWORDS_IN_BLOCK = ARGON2_BLOCK_SIZE / 16, + ARGON2_HWORDS_IN_BLOCK = ARGON2_BLOCK_SIZE / 32, + ARGON2_512BIT_WORDS_IN_BLOCK = ARGON2_BLOCK_SIZE / 64, + /* Number of pseudo-random values generated by one call to Blake in + Argon2i to generate reference block positions */ + ARGON2_ADDRESSES_IN_BLOCK = 128, + /* 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. * 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; -/*****************Functions that work with the block******************/ - -/* Initialize each byte of the block with @in */ -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); +void init_block_value(block *, uint8_t); +void copy_block(block *, const block *); +void xor_block(block *, const block *); /* - * Argon2 instance: memory pointer, number of passes, amount of memory, type, - * and derived values. - * Used to evaluate the number and location of blocks to construct in each - * thread + * Argon2 instance: memory pointer, number of passes, amount of memory, + * type, and derived values. Used to evaluate the number and location of + * blocks to construct in each thread. */ typedef struct Argon2_instance_t { - block *memory; /* Memory pointer */ - uint32_t version; - 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_context *context_ptr; /* points back to original context */ + block *memory; /* Memory pointer */ + uint32_t version; + 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_context *context_ptr; /* points back to original context */ } argon2_instance_t; /* - * Argon2 position: where we construct the block right now. Used to distribute - * work between threads. + * Argon2 position: where we construct the block right now. Used to + * distribute work between threads. */ typedef struct Argon2_position_t { - uint32_t pass; - uint32_t lane; - uint8_t slice; - uint32_t index; + uint32_t pass; + uint32_t lane; + 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_instance_t *instance_ptr; + argon2_position_t pos; } 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 - * 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, - 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 - */ -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 +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_THIRD_PARTY_ARGON2_CORE_H_ */ diff --git a/third_party/argon2/encoding.c b/third_party/argon2/encoding.c index dad92075a..cd9bff6a4 100644 --- a/third_party/argon2/encoding.c +++ b/third_party/argon2/encoding.c @@ -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/limits.h" #include "libc/str/str.h" #include "third_party/argon2/core.h" #include "third_party/argon2/encoding.h" -/* clang-format off */ -/* - * 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. - */ +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 */ /* * 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. */ +/** + * 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) { /* check for prefix */ @@ -370,6 +387,14 @@ int decode_string(argon2_context *ctx, const char *str, argon2_type type) { #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, argon2_type type) { #define SS(str) \ @@ -437,9 +462,9 @@ int encode_string(char *dst, size_t dst_len, argon2_context *ctx, #undef SB } +/** Returns length of the encoded byte stream with length len */ size_t b64len(uint32_t len) { size_t olen = ((size_t)len / 3) << 2; - switch (len % 3) { case 2: olen++; @@ -448,10 +473,10 @@ size_t b64len(uint32_t len) { olen += 2; break; } - return olen; } +/** Returns length of the encoded number num */ size_t numlen(uint32_t num) { size_t len = 1; while (num >= 10) { diff --git a/third_party/argon2/encoding.h b/third_party/argon2/encoding.h index a1ad131a8..538d770f5 100644 --- a/third_party/argon2/encoding.h +++ b/third_party/argon2/encoding.h @@ -1,58 +1,18 @@ -/* - * 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. - */ - -#ifndef ENCODING_H -#define ENCODING_H +#ifndef COSMOPOLITAN_THIRD_PARTY_ARGON2_ENCODING_H_ +#define COSMOPOLITAN_THIRD_PARTY_ARGON2_ENCODING_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_OUT_LEN UINT32_C(12) +#define ARGON2_MIN_DECODED_OUT_LEN UINT32_C(12) -/* -* encode 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. -* -* on success, ARGON2_OK is returned. -*/ -int encode_string(char *dst, size_t dst_len, argon2_context *ctx, - argon2_type type); +int encode_string(char *, size_t, argon2_context *, argon2_type); +int decode_string(argon2_context *, const char *, argon2_type); +size_t b64len(uint32_t); +size_t numlen(uint32_t); -/* -* 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. -* -* 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 +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_THIRD_PARTY_ARGON2_ENCODING_H_ */ diff --git a/third_party/argon2/ref.c b/third_party/argon2/ref.c index 3599d6e5a..2ce1e832b 100644 --- a/third_party/argon2/ref.c +++ b/third_party/argon2/ref.c @@ -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 "third_party/argon2/argon2.h" #include "third_party/argon2/blake2-impl.h" #include "third_party/argon2/blake2.h" #include "third_party/argon2/blamka-round-ref.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 */ /* @@ -85,6 +107,15 @@ static void next_addresses(block *address_block, block *input_block, 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, argon2_position_t position) { block *ref_block = NULL, *curr_block = NULL; diff --git a/tool/net/largon2.c b/tool/net/largon2.c index e7dcafc55..157ae854d 100644 --- a/tool/net/largon2.c +++ b/tool/net/largon2.c @@ -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 -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. +Lua C binding for the Argon2 password hashing function. +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. This module's version is compatible with Argon2 [20161029](https://github.com/P-H-C/phc-winner-argon2/releases/tag/20161029) @@ -19,15 +60,6 @@ original implementaiton. @release 3.0.1 */ - -#include -#include -#include -#include -#include -#include - - #ifndef LUA_51 #if !defined(LUA_VERSION_NUM) || LUA_VERSION_NUM < 502 #define LUA_51 1