packages feed

argon2 1.1.0 → 1.2.0

raw patch · 18 files changed

+1347/−269 lines, 18 filesdep ~basePVP ok

version bump matches the API change (PVP)

Dependency ranges changed: base

API changes (from Hackage documentation)

- Crypto.Argon2: instance GHC.Generics.Constructor Crypto.Argon2.C1_0Argon2Variant
- Crypto.Argon2: instance GHC.Generics.Constructor Crypto.Argon2.C1_0HashOptions
- Crypto.Argon2: instance GHC.Generics.Constructor Crypto.Argon2.C1_1Argon2Variant
- Crypto.Argon2: instance GHC.Generics.Datatype Crypto.Argon2.D1Argon2Variant
- Crypto.Argon2: instance GHC.Generics.Datatype Crypto.Argon2.D1HashOptions
- Crypto.Argon2: instance GHC.Generics.Selector Crypto.Argon2.S1_0_0HashOptions
- Crypto.Argon2: instance GHC.Generics.Selector Crypto.Argon2.S1_0_1HashOptions
- Crypto.Argon2: instance GHC.Generics.Selector Crypto.Argon2.S1_0_2HashOptions
- Crypto.Argon2: instance GHC.Generics.Selector Crypto.Argon2.S1_0_3HashOptions
+ Crypto.Argon2.FFI: argon2_encodedlen :: (Word32) -> (Word32) -> (Word32) -> (Word32) -> (Word32) -> IO CSize
- Crypto.Argon2: Argon2PasswordLengthOutOfRange :: !Word64 -> Argon2Exception
+ Crypto.Argon2: Argon2PasswordLengthOutOfRange :: !CSize -> Argon2Exception
- Crypto.Argon2: Argon2SaltLengthOutOfRange :: !Word64 -> Argon2Exception
+ Crypto.Argon2: Argon2SaltLengthOutOfRange :: !CSize -> Argon2Exception
- Crypto.Argon2.FFI: argon2d_hash_encoded :: (Word32) -> (Word32) -> (Word32) -> Ptr a -> (Word64) -> Ptr b -> (Word64) -> (Word64) -> CString -> (Word64) -> IO (Int32)
+ Crypto.Argon2.FFI: argon2d_hash_encoded :: (Word32) -> (Word32) -> (Word32) -> Ptr a -> CSize -> Ptr b -> CSize -> CSize -> CString -> CSize -> IO (Int32)
- Crypto.Argon2.FFI: argon2d_hash_raw :: (Word32) -> (Word32) -> (Word32) -> Ptr a -> (Word64) -> Ptr b -> (Word64) -> Ptr c -> (Word64) -> IO (Int32)
+ Crypto.Argon2.FFI: argon2d_hash_raw :: (Word32) -> (Word32) -> (Word32) -> Ptr a -> CSize -> Ptr b -> CSize -> Ptr c -> CSize -> IO (Int32)
- Crypto.Argon2.FFI: argon2d_verify :: CString -> Ptr a -> (Word64) -> IO (Int32)
+ Crypto.Argon2.FFI: argon2d_verify :: CString -> Ptr a -> CSize -> IO (Int32)
- Crypto.Argon2.FFI: argon2i_hash_encoded :: (Word32) -> (Word32) -> (Word32) -> Ptr a -> (Word64) -> Ptr b -> (Word64) -> (Word64) -> CString -> (Word64) -> IO (Int32)
+ Crypto.Argon2.FFI: argon2i_hash_encoded :: (Word32) -> (Word32) -> (Word32) -> Ptr a -> CSize -> Ptr b -> CSize -> CSize -> CString -> CSize -> IO (Int32)
- Crypto.Argon2.FFI: argon2i_hash_raw :: (Word32) -> (Word32) -> (Word32) -> Ptr a -> (Word64) -> Ptr b -> (Word64) -> Ptr c -> (Word64) -> IO (Int32)
+ Crypto.Argon2.FFI: argon2i_hash_raw :: (Word32) -> (Word32) -> (Word32) -> Ptr a -> CSize -> Ptr b -> CSize -> Ptr c -> CSize -> IO (Int32)
- Crypto.Argon2.FFI: argon2i_verify :: CString -> Ptr a -> (Word64) -> IO (Int32)
+ Crypto.Argon2.FFI: argon2i_verify :: CString -> Ptr a -> CSize -> IO (Int32)

Files

Changelog.md view
@@ -1,3 +1,24 @@+# 1.2.0++- Updated embedded phc-winner-argon2, so that hashes are generated+  using version 1.3 of the argon2 specification.+  +  Note that that hashes generated using this version are different than+  hashes generated using previous versions, so anything that compares them+  or relies on them being stable may be broken by this update. +  However, Crypto.Argon2.verify will continue to be able to verify+  hashes produced by previous versions.++- Use CSize for portability instead of Word64, fixing build on 32 bit+  systems. This changed the constructors of Argon2Exception, an API change.++- Bug fix: Crypto.Argon2.hash returned a ByteString truncated at the first+  NULL.++- Added use-system-library build flag.++- Build against `base-4.9`+ # 1.1.0  - First stable release. Same API as 1.0.0, but now features documentation and
argon2.cabal view
@@ -1,5 +1,5 @@ name:                argon2-version:             1.1.0+version:             1.2.0 synopsis:            Haskell bindings to libargon2 - the reference implementation of the Argon2 password-hashing function -- description:          homepage:            https://github.com/ocharles/argon2.git@@ -12,20 +12,36 @@ build-type:          Simple extra-source-files:  Changelog.md cabal-version:       >=1.10+extra-source-files: phc-winner-argon2/src/blake2/blake2.h+                    phc-winner-argon2/src/blake2/blake2-impl.h+                    phc-winner-argon2/src/blake2/blamka-round-ref.h+                    phc-winner-argon2/include/argon2.h +flag use-system-library+  description: Link against system libargon2 library rather than embedded copy+  default: False+ library   exposed-modules:     Crypto.Argon2.FFI                        Crypto.Argon2-  build-depends:       base >=4.8 && <4.9, bytestring, text, transformers+  build-depends:       base >=4.8 && <4.10, bytestring, text, transformers   hs-source-dirs:      src   default-language:    Haskell2010-  c-sources: phc-winner-argon2/src/argon2.c-             phc-winner-argon2/src/core.c-             phc-winner-argon2/src/blake2/blake2b.c-             phc-winner-argon2/src/thread.c-             phc-winner-argon2/src/ref.c-             phc-winner-argon2/src/encoding.c-  include-dirs: phc-winner-argon2/src+  if flag(use-system-library)+    extra-libraries: argon2+  else+    c-sources: phc-winner-argon2/src/argon2.c+               phc-winner-argon2/src/core.c+               phc-winner-argon2/src/blake2/blake2b.c+               phc-winner-argon2/src/thread.c+               phc-winner-argon2/src/ref.c+               phc-winner-argon2/src/encoding.c+               phc-winner-argon2/src/encoding.h+               phc-winner-argon2/src/core.h+               phc-winner-argon2/src/thread.h+               phc-winner-argon2/src/ref.h+    include-dirs: phc-winner-argon2/src+                  phc-winner-argon2/include  test-suite tests   type: exitcode-stdio-1.0
+ phc-winner-argon2/include/argon2.h view
@@ -0,0 +1,374 @@+/*+ * Argon2 source code package+ *+ * Written by Daniel Dinu and Dmitry Khovratovich, 2015+ *+ * This work is licensed under a Creative Commons CC0 1.0 License/Waiver.+ *+ * You should have received a copy of the CC0 Public Domain Dedication+ * along with this software. If not, see+ * <http://creativecommons.org/publicdomain/zero/1.0/>.+ */++#ifndef ARGON2_H+#define ARGON2_H++#include <stdint.h>+#include <stddef.h>+#include <limits.h>++#if defined(__cplusplus)+extern "C" {+#endif++/* Symbols visibility control */+#ifdef A2_VISCTL+#define ARGON2_PUBLIC __attribute__((visibility("default")))+#elif _MSC_VER+#define ARGON2_PUBLIC __declspec(dllexport)+#else+#define ARGON2_PUBLIC+#endif++/*+ * Argon2 input parameter restrictions+ */++/* Minimum and maximum number of lanes (degree of parallelism) */+#define ARGON2_MIN_LANES UINT32_C(1)+#define ARGON2_MAX_LANES UINT32_C(0xFFFFFF)++/* Minimum and maximum number of threads */+#define ARGON2_MIN_THREADS UINT32_C(1)+#define ARGON2_MAX_THREADS UINT32_C(0xFFFFFF)++/* Number of synchronization points between lanes per pass */+#define ARGON2_SYNC_POINTS UINT32_C(4)++/* Minimum and maximum digest size in bytes */+#define ARGON2_MIN_OUTLEN UINT32_C(4)+#define ARGON2_MAX_OUTLEN UINT32_C(0xFFFFFFFF)++/* Minimum and maximum number of memory blocks (each of BLOCK_SIZE bytes) */+#define ARGON2_MIN_MEMORY (2 * ARGON2_SYNC_POINTS) /* 2 blocks per slice */++#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)++/* Minimum and maximum number of passes */+#define ARGON2_MIN_TIME UINT32_C(1)+#define ARGON2_MAX_TIME UINT32_C(0xFFFFFFFF)++/* Minimum and maximum password length in bytes */+#define ARGON2_MIN_PWD_LENGTH UINT32_C(0)+#define ARGON2_MAX_PWD_LENGTH UINT32_C(0xFFFFFFFF)++/* Minimum and maximum associated data length in bytes */+#define ARGON2_MIN_AD_LENGTH UINT32_C(0)+#define ARGON2_MAX_AD_LENGTH UINT32_C(0xFFFFFFFF)++/* Minimum and maximum salt length in bytes */+#define ARGON2_MIN_SALT_LENGTH UINT32_C(8)+#define ARGON2_MAX_SALT_LENGTH UINT32_C(0xFFFFFFFF)++/* Minimum and maximum key length in bytes */+#define ARGON2_MIN_SECRET UINT32_C(0)+#define ARGON2_MAX_SECRET UINT32_C(0xFFFFFFFF)++#define ARGON2_FLAG_CLEAR_PASSWORD (UINT32_C(1) << 0)+#define ARGON2_FLAG_CLEAR_SECRET (UINT32_C(1) << 1)+#define ARGON2_FLAG_CLEAR_MEMORY (UINT32_C(1) << 2)+#define ARGON2_DEFAULT_FLAGS (ARGON2_FLAG_CLEAR_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_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:+ *  output array and its length,+ *  password and its length,+ *  salt and its length,+ *  secret and its length,+ *  associated data and its length,+ *  number of passes, amount of used memory (in KBytes, can be rounded up a bit)+ *  number of parallel threads that will be run.+ * All the parameters above affect the output hash value.+ * Additionally, two function pointers can be provided to allocate and+ * deallocate the memory (if NULL, memory will be allocated internally).+ * Also, three flags indicate whether to erase password, secret as soon as they+ * are pre-hashed (and thus not needed anymore), and the entire memory+ *****+ * Simplest situation: you have output array out[8], password is stored in+ * pwd[32], salt is stored in salt[16], you do not have keys nor associated+ * data. You need to spend 1 GB of RAM and you run 5 passes of Argon2d with+ * 4 parallel lanes.+ * You want to erase the password, but you're OK with last pass not being+ * erased. You want to use the default memory allocator.+ * Then you initialize:+ Argon2_Context(out,8,pwd,32,salt,16,NULL,0,NULL,0,5,1<<20,4,4,NULL,NULL,true,false,false,false)+ */+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 */+} argon2_context;++/* Argon2 primitive type */+typedef enum Argon2_type { Argon2_d = 0, Argon2_i = 1 } 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;++/*+ * 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 by allocating memory 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);++/* 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);++/* 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);++/**+ * 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);++/* 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+ * @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);++#if defined(__cplusplus)+}+#endif++#endif
phc-winner-argon2/src/argon2.c view
@@ -19,94 +19,8 @@ #include "encoding.h" #include "core.h" -/* Error messages */-static const char *Argon2_ErrorMessage[] = {-    /*{ARGON2_OK, */ "OK",-    /*}, -    {ARGON2_OUTPUT_PTR_NULL, */ "Output pointer is NULL",-    /*},--{ARGON2_OUTPUT_TOO_SHORT, */ "Output is too short",-    /*},-{ARGON2_OUTPUT_TOO_LONG, */ "Output is too long",-    /*},--{ARGON2_PWD_TOO_SHORT, */ "Password is too short",-    /*},-{ARGON2_PWD_TOO_LONG, */ "Password is too long",-    /*},--{ARGON2_SALT_TOO_SHORT, */ "Salt is too short",-    /*},-{ARGON2_SALT_TOO_LONG, */ "Salt is too long",-    /*},--{ARGON2_AD_TOO_SHORT, */ "Associated data is too short",-    /*},-{ARGON2_AD_TOO_LONG, */ "Associated date is too long",-    /*},--{ARGON2_SECRET_TOO_SHORT, */ "Secret is too short",-    /*},-{ARGON2_SECRET_TOO_LONG, */ "Secret is too long",-    /*},--{ARGON2_TIME_TOO_SMALL, */ "Time cost is too small",-    /*},-{ARGON2_TIME_TOO_LARGE, */ "Time cost is too large",-    /*},--{ARGON2_MEMORY_TOO_LITTLE, */ "Memory cost is too small",-    /*},-{ARGON2_MEMORY_TOO_MUCH, */ "Memory cost is too large",-    /*},--{ARGON2_LANES_TOO_FEW, */ "Too few lanes",-    /*},-{ARGON2_LANES_TOO_MANY, */ "Too many lanes",-    /*},--{ARGON2_PWD_PTR_MISMATCH, */ "Password pointer is NULL, but password length is not 0",-    /*},-{ARGON2_SALT_PTR_MISMATCH, */ "Salt pointer is NULL, but salt length is not 0",-    /*},-{ARGON2_SECRET_PTR_MISMATCH, */ "Secret pointer is NULL, but secret length is not 0",-    /*},-{ARGON2_AD_PTR_MISMATCH, */ "Associated data pointer is NULL, but ad length is not 0",-    /*},--{ARGON2_MEMORY_ALLOCATION_ERROR, */ "Memory allocation error",-    /*},--{ARGON2_FREE_MEMORY_CBK_NULL, */ "The free memory callback is NULL",-    /*},-{ARGON2_ALLOCATE_MEMORY_CBK_NULL, */ "The allocate memory callback is NULL",-    /*},--{ARGON2_INCORRECT_PARAMETER, */ "Argon2_Context context is NULL",-    /*},-{ARGON2_INCORRECT_TYPE, */ "There is no such version of Argon2",-    /*},--{ARGON2_OUT_PTR_MISMATCH, */ "Output pointer mismatch",-    /*},--{ARGON2_THREADS_TOO_FEW, */ "Not enough threads",-    /*},-{ARGON2_THREADS_TOO_MANY, */ "Too many threads",-    /*},-{ARGON2_MISSING_ARGS, */ "Missing arguments",-    /*},-{ARGON2_ENCODING_FAIL, */ "Encoding failed",-    /*},-{ARGON2_DECODING_FAIL, */ "Decoding failed",-    /*},-{ARGON2_THREAD_FAIL */ "Threading failure", /*},*/-};---int argon2_core(argon2_context *context, argon2_type type) {+int argon2_ctx(argon2_context *context, argon2_type type) {     /* 1. Validate all inputs */     int result = validate_inputs(context);     uint32_t memory_blocks, segment_length;@@ -132,6 +46,7 @@     /* Ensure that all segments have equal length */     memory_blocks = segment_length * (context->lanes * ARGON2_SYNC_POINTS); +    instance.version = context->version;     instance.memory = NULL;     instance.passes = context->t_cost;     instance.memory_blocks = memory_blocks;@@ -162,29 +77,23 @@     return ARGON2_OK; } - int argon2_hash(const uint32_t t_cost, const uint32_t m_cost,                 const uint32_t parallelism, const void *pwd,                 const size_t pwdlen, const void *salt, const size_t saltlen,                 void *hash, const size_t hashlen, char *encoded,-                const size_t encodedlen, argon2_type type) {+                const size_t encodedlen, argon2_type type, +                const uint32_t version){      argon2_context context;     int result;     uint8_t *out; -    /* Detect and reject overflowing sizes */-    /* TODO: This should probably be fixed in the function signature */-    if (pwdlen > UINT32_MAX) {-        return ARGON2_PWD_TOO_LONG;-    }--    if (hashlen > UINT32_MAX) {+    if (hashlen > ARGON2_MAX_OUTLEN) {         return ARGON2_OUTPUT_TOO_LONG;     } -    if (saltlen > UINT32_MAX) {-        return ARGON2_SALT_TOO_LONG;+    if (hashlen < ARGON2_MIN_OUTLEN) {+        return ARGON2_OUTPUT_TOO_SHORT;     }      out = malloc(hashlen);@@ -209,11 +118,12 @@     context.allocate_cbk = NULL;     context.free_cbk = NULL;     context.flags = ARGON2_DEFAULT_FLAGS;+    context.version = version; -    result = argon2_core(&context, type);+    result = argon2_ctx(&context, type);      if (result != ARGON2_OK) {-        memset(out, 0x00, hashlen);+        secure_wipe_memory(out, hashlen);         free(out);         return result;     }@@ -225,14 +135,14 @@      /* if encoding requested, write it */     if (encoded && encodedlen) {-        if (!encode_string(encoded, encodedlen, &context, type)) {-            memset(out, 0x00, hashlen);-            memset(encoded, 0x00, encodedlen);+        if (encode_string(encoded, encodedlen, &context, type) != ARGON2_OK) {+            secure_wipe_memory(out, hashlen); /* wipe buffers if error */+            secure_wipe_memory(encoded, encodedlen);             free(out);             return ARGON2_ENCODING_FAIL;         }     }-+    secure_wipe_memory(out, hashlen);     free(out);      return ARGON2_OK;@@ -245,7 +155,8 @@                          char *encoded, const size_t encodedlen) {      return argon2_hash(t_cost, m_cost, parallelism, pwd, pwdlen, salt, saltlen,-                       NULL, hashlen, encoded, encodedlen, Argon2_i);+                       NULL, hashlen, encoded, encodedlen, Argon2_i,+                       ARGON2_VERSION_NUMBER); }  int argon2i_hash_raw(const uint32_t t_cost, const uint32_t m_cost,@@ -254,7 +165,7 @@                      const size_t saltlen, void *hash, const size_t hashlen) {      return argon2_hash(t_cost, m_cost, parallelism, pwd, pwdlen, salt, saltlen,-                       hash, hashlen, NULL, 0, Argon2_i);+                       hash, hashlen, NULL, 0, Argon2_i, ARGON2_VERSION_NUMBER); }  int argon2d_hash_encoded(const uint32_t t_cost, const uint32_t m_cost,@@ -264,7 +175,8 @@                          char *encoded, const size_t encodedlen) {      return argon2_hash(t_cost, m_cost, parallelism, pwd, pwdlen, salt, saltlen,-                       NULL, hashlen, encoded, encodedlen, Argon2_d);+                       NULL, hashlen, encoded, encodedlen, Argon2_d,+                       ARGON2_VERSION_NUMBER); }  int argon2d_hash_raw(const uint32_t t_cost, const uint32_t m_cost,@@ -273,7 +185,7 @@                      const size_t saltlen, void *hash, const size_t hashlen) {      return argon2_hash(t_cost, m_cost, parallelism, pwd, pwdlen, salt, saltlen,-                       hash, hashlen, NULL, 0, Argon2_d);+                       hash, hashlen, NULL, 0, Argon2_d, ARGON2_VERSION_NUMBER); }  static int argon2_compare(const uint8_t *b1, const uint8_t *b2, size_t len) {@@ -292,12 +204,30 @@     argon2_context ctx;     uint8_t *out;     int ret;+    int decode_result;+    uint32_t encoded_len;+    size_t encoded_len_tmp; +    if(encoded == NULL) {+        return ARGON2_DECODING_FAIL;+    }++    encoded_len_tmp = strlen(encoded);     /* max values, to be updated in decode_string */-    ctx.adlen = 512;-    ctx.saltlen = 512;-    ctx.outlen = 512;+    if (UINT32_MAX < encoded_len_tmp) {+        return ARGON2_DECODING_FAIL;+    } +    encoded_len = (uint32_t)encoded_len_tmp;+    ctx.adlen = encoded_len;+    ctx.saltlen = encoded_len;+    ctx.outlen = encoded_len;+    ctx.allocate_cbk = NULL;+    ctx.free_cbk = NULL;+    ctx.secret = NULL;+    ctx.secretlen = 0;+    ctx.pwdlen = 0;+    ctx.pwd = NULL;     ctx.ad = malloc(ctx.adlen);     ctx.salt = malloc(ctx.saltlen);     ctx.out = malloc(ctx.outlen);@@ -314,30 +244,29 @@         free(ctx.out);         return ARGON2_MEMORY_ALLOCATION_ERROR;     }--    if(decode_string(&ctx, encoded, type) != 1) {+    decode_result = decode_string(&ctx, encoded, type);+    if (decode_result != ARGON2_OK) {         free(ctx.ad);         free(ctx.salt);         free(ctx.out);         free(out);-        return ARGON2_DECODING_FAIL;+        return decode_result;     } -    ret = argon2_hash(ctx.t_cost, ctx.m_cost, ctx.threads, pwd, pwdlen, ctx.salt,-                ctx.saltlen, out, ctx.outlen, NULL, 0, type);+    ret = argon2_hash(ctx.t_cost, ctx.m_cost, ctx.threads, pwd, pwdlen,+                      ctx.salt, ctx.saltlen, out, ctx.outlen, NULL, 0, type,+                      ctx.version);      free(ctx.ad);     free(ctx.salt); -    if (ret != ARGON2_OK || argon2_compare(out, ctx.out, ctx.outlen)) {-        free(out);-        free(ctx.out);-        return ARGON2_DECODING_FAIL;+    if (ret == ARGON2_OK && argon2_compare(out, ctx.out, ctx.outlen)) {+        ret = ARGON2_VERIFY_MISMATCH;     }     free(out);     free(ctx.out); -    return ARGON2_OK;+    return ret; }  int argon2i_verify(const char *encoded, const void *pwd, const size_t pwdlen) {@@ -350,17 +279,22 @@     return argon2_verify(encoded, pwd, pwdlen, Argon2_d); } -int argon2d(argon2_context *context) { return argon2_core(context, Argon2_d); }+int argon2d_ctx(argon2_context *context) {+    return argon2_ctx(context, Argon2_d);+} -int argon2i(argon2_context *context) { return argon2_core(context, Argon2_i); }+int argon2i_ctx(argon2_context *context) {+    return argon2_ctx(context, Argon2_i);+} -int verify_d(argon2_context *context, const char *hash) {+int argon2_verify_ctx(argon2_context *context, const char *hash,+                      argon2_type type) {     int result;     if (0 == context->outlen || NULL == hash) {         return ARGON2_OUT_PTR_MISMATCH;     } -    result = argon2_core(context, Argon2_d);+    result = argon2_ctx(context, type);      if (ARGON2_OK != result) {         return result;@@ -369,33 +303,96 @@     return 0 == memcmp(hash, context->out, context->outlen); } -int verify_i(argon2_context *context, const char *hash) {-    int result;-    if (0 == context->outlen || NULL == hash) {-        return ARGON2_OUT_PTR_MISMATCH;-    }+int argon2d_verify_ctx(argon2_context *context, const char *hash) {+    return argon2_verify_ctx(context, hash, Argon2_d);+} -    result = argon2_core(context, Argon2_i);+int argon2i_verify_ctx(argon2_context *context, const char *hash) {+    return argon2_verify_ctx(context, hash, Argon2_i);+} -    if (ARGON2_OK != result) {-        return result;+const char *argon2_error_message(int error_code) {+    switch (error_code) {+    case ARGON2_OK:+        return "OK";+    case ARGON2_OUTPUT_PTR_NULL:+        return "Output pointer is NULL";+    case ARGON2_OUTPUT_TOO_SHORT:+        return "Output is too short";+    case ARGON2_OUTPUT_TOO_LONG:+        return "Output is too long";+    case ARGON2_PWD_TOO_SHORT:+        return "Password is too short";+    case ARGON2_PWD_TOO_LONG:+        return "Password is too long";+    case ARGON2_SALT_TOO_SHORT:+        return "Salt is too short";+    case ARGON2_SALT_TOO_LONG:+        return "Salt is too long";+    case ARGON2_AD_TOO_SHORT:+        return "Associated data is too short";+    case ARGON2_AD_TOO_LONG:+        return "Associated data is too long";+    case ARGON2_SECRET_TOO_SHORT:+        return "Secret is too short";+    case ARGON2_SECRET_TOO_LONG:+        return "Secret is too long";+    case ARGON2_TIME_TOO_SMALL:+        return "Time cost is too small";+    case ARGON2_TIME_TOO_LARGE:+        return "Time cost is too large";+    case ARGON2_MEMORY_TOO_LITTLE:+        return "Memory cost is too small";+    case ARGON2_MEMORY_TOO_MUCH:+        return "Memory cost is too large";+    case ARGON2_LANES_TOO_FEW:+        return "Too few lanes";+    case ARGON2_LANES_TOO_MANY:+        return "Too many lanes";+    case ARGON2_PWD_PTR_MISMATCH:+        return "Password pointer is NULL, but password length is not 0";+    case ARGON2_SALT_PTR_MISMATCH:+        return "Salt pointer is NULL, but salt length is not 0";+    case ARGON2_SECRET_PTR_MISMATCH:+        return "Secret pointer is NULL, but secret length is not 0";+    case ARGON2_AD_PTR_MISMATCH:+        return "Associated data pointer is NULL, but ad length is not 0";+    case ARGON2_MEMORY_ALLOCATION_ERROR:+        return "Memory allocation error";+    case ARGON2_FREE_MEMORY_CBK_NULL:+        return "The free memory callback is NULL";+    case ARGON2_ALLOCATE_MEMORY_CBK_NULL:+        return "The allocate memory callback is NULL";+    case ARGON2_INCORRECT_PARAMETER:+        return "Argon2_Context context is NULL";+    case ARGON2_INCORRECT_TYPE:+        return "There is no such version of Argon2";+    case ARGON2_OUT_PTR_MISMATCH:+        return "Output pointer mismatch";+    case ARGON2_THREADS_TOO_FEW:+        return "Not enough threads";+    case ARGON2_THREADS_TOO_MANY:+        return "Too many threads";+    case ARGON2_MISSING_ARGS:+        return "Missing arguments";+    case ARGON2_ENCODING_FAIL:+        return "Encoding failed";+    case ARGON2_DECODING_FAIL:+        return "Decoding failed";+    case ARGON2_THREAD_FAIL:+        return "Threading failure";+    case ARGON2_DECODING_LENGTH_FAIL:+        return "Some of encoded parameters are too long or too short";+    case ARGON2_VERIFY_MISMATCH:+        return "The password does not match the supplied hash";+    default:+        return "Unknown error code";     }--    return 0 == memcmp(hash, context->out, context->outlen); } --const char *error_message(int error_code) {-    enum {-        /* Make sure---at compile time---that the enum size matches the array-           size */-        ERROR_STRING_CHECK =-            1 /-            !!((sizeof(Argon2_ErrorMessage) / sizeof(Argon2_ErrorMessage[0])) ==-               ARGON2_ERROR_CODES_LENGTH)-    };-    if (error_code >= 0 && error_code < ARGON2_ERROR_CODES_LENGTH) {-        return Argon2_ErrorMessage[(argon2_error_codes)error_code];-    }-    return "Unknown error code.";+size_t argon2_encodedlen(uint32_t t_cost, uint32_t m_cost, uint32_t parallelism,+                         uint32_t saltlen, uint32_t hashlen) {+    return strlen("$argon2x$v=$m=,t=,p=$$") + numlen(t_cost) + numlen(m_cost)+        + numlen(parallelism) + b64len(saltlen) + b64len(hashlen)+        + numlen(ARGON2_VERSION_NUMBER) + 1; }
+ phc-winner-argon2/src/blake2/blake2-impl.h view
@@ -0,0 +1,139 @@+#ifndef PORTABLE_BLAKE2_IMPL_H+#define PORTABLE_BLAKE2_IMPL_H++#include <stdint.h>+#include <string.h>++#if defined(_MSC_VER)+#define BLAKE2_INLINE __inline+#elif defined(__GNUC__) || defined(__clang__)+#define BLAKE2_INLINE __inline__+#else+#define BLAKE2_INLINE+#endif++/* Argon2 Team - Begin Code */+/*+   Not an exhaustive list, but should cover the majority of modern platforms+   Additionally, the code will always be correct---this is only a performance+   tweak.+*/+#if (defined(__BYTE_ORDER__) &&                                                \+     (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__)) ||                           \+    defined(__LITTLE_ENDIAN__) || defined(__ARMEL__) || defined(__MIPSEL__) || \+    defined(__AARCH64EL__) || defined(__amd64__) || defined(__i386__) ||       \+    defined(_M_IX86) || defined(_M_X64) || defined(_M_AMD64) ||                \+    defined(_M_ARM)+#define NATIVE_LITTLE_ENDIAN+#endif+/* Argon2 Team - End Code */++static BLAKE2_INLINE uint32_t load32(const void *src) {+#if defined(NATIVE_LITTLE_ENDIAN)+    uint32_t w;+    memcpy(&w, src, sizeof w);+    return w;+#else+    const uint8_t *p = (const uint8_t *)src;+    uint32_t w = *p++;+    w |= (uint32_t)(*p++) << 8;+    w |= (uint32_t)(*p++) << 16;+    w |= (uint32_t)(*p++) << 24;+    return w;+#endif+}++static BLAKE2_INLINE uint64_t load64(const void *src) {+#if defined(NATIVE_LITTLE_ENDIAN)+    uint64_t w;+    memcpy(&w, src, sizeof w);+    return w;+#else+    const uint8_t *p = (const uint8_t *)src;+    uint64_t w = *p++;+    w |= (uint64_t)(*p++) << 8;+    w |= (uint64_t)(*p++) << 16;+    w |= (uint64_t)(*p++) << 24;+    w |= (uint64_t)(*p++) << 32;+    w |= (uint64_t)(*p++) << 40;+    w |= (uint64_t)(*p++) << 48;+    w |= (uint64_t)(*p++) << 56;+    return w;+#endif+}++static BLAKE2_INLINE void store32(void *dst, uint32_t w) {+#if defined(NATIVE_LITTLE_ENDIAN)+    memcpy(dst, &w, sizeof w);+#else+    uint8_t *p = (uint8_t *)dst;+    *p++ = (uint8_t)w;+    w >>= 8;+    *p++ = (uint8_t)w;+    w >>= 8;+    *p++ = (uint8_t)w;+    w >>= 8;+    *p++ = (uint8_t)w;+#endif+}++static BLAKE2_INLINE void store64(void *dst, uint64_t w) {+#if defined(NATIVE_LITTLE_ENDIAN)+    memcpy(dst, &w, sizeof w);+#else+    uint8_t *p = (uint8_t *)dst;+    *p++ = (uint8_t)w;+    w >>= 8;+    *p++ = (uint8_t)w;+    w >>= 8;+    *p++ = (uint8_t)w;+    w >>= 8;+    *p++ = (uint8_t)w;+    w >>= 8;+    *p++ = (uint8_t)w;+    w >>= 8;+    *p++ = (uint8_t)w;+    w >>= 8;+    *p++ = (uint8_t)w;+    w >>= 8;+    *p++ = (uint8_t)w;+#endif+}++static BLAKE2_INLINE uint64_t load48(const void *src) {+    const uint8_t *p = (const uint8_t *)src;+    uint64_t w = *p++;+    w |= (uint64_t)(*p++) << 8;+    w |= (uint64_t)(*p++) << 16;+    w |= (uint64_t)(*p++) << 24;+    w |= (uint64_t)(*p++) << 32;+    w |= (uint64_t)(*p++) << 40;+    return w;+}++static BLAKE2_INLINE void store48(void *dst, uint64_t w) {+    uint8_t *p = (uint8_t *)dst;+    *p++ = (uint8_t)w;+    w >>= 8;+    *p++ = (uint8_t)w;+    w >>= 8;+    *p++ = (uint8_t)w;+    w >>= 8;+    *p++ = (uint8_t)w;+    w >>= 8;+    *p++ = (uint8_t)w;+    w >>= 8;+    *p++ = (uint8_t)w;+}++static BLAKE2_INLINE uint32_t rotr32(const uint32_t w, const unsigned c) {+    return (w >> c) | (w << (32 - c));+}++static BLAKE2_INLINE uint64_t rotr64(const uint64_t w, const unsigned c) {+    return (w >> c) | (w << (64 - c));+}++void secure_wipe_memory(void *v, size_t n);++#endif
+ phc-winner-argon2/src/blake2/blake2.h view
@@ -0,0 +1,74 @@+#ifndef PORTABLE_BLAKE2_H+#define PORTABLE_BLAKE2_H++#include <stddef.h>+#include <stdint.h>+#include <limits.h>++#if defined(__cplusplus)+extern "C" {+#endif++enum blake2b_constant {+    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 */+} 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;+} 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 */+int blake2b_init(blake2b_state *S, size_t outlen);+int blake2b_init_key(blake2b_state *S, size_t outlen, const void *key,+                     size_t keylen);+int blake2b_init_param(blake2b_state *S, const blake2b_param *P);+int blake2b_update(blake2b_state *S, const void *in, size_t inlen);+int blake2b_final(blake2b_state *S, void *out, size_t outlen);++/* Simple API */+int blake2b(void *out, size_t outlen, const void *in, size_t inlen,+            const void *key, size_t keylen);++/* Argon2 Team - Begin Code */+int blake2b_long(void *out, size_t outlen, const void *in, size_t inlen);+/* Argon2 Team - End Code */++#if defined(__cplusplus)+}+#endif++#endif
phc-winner-argon2/src/blake2/blake2b.c view
@@ -44,7 +44,7 @@ }  static BLAKE2_INLINE void blake2b_invalidate_state(blake2b_state *S) {-    burn(S, sizeof(*S));      /* wipe */+    secure_wipe_memory(S, sizeof(*S));      /* wipe */     blake2b_set_lastblock(S); /* invalidate for further use */ } @@ -140,7 +140,7 @@         memset(block, 0, BLAKE2B_BLOCKBYTES);         memcpy(block, key, keylen);         blake2b_update(S, block, BLAKE2B_BLOCKBYTES);-        burn(block, BLAKE2B_BLOCKBYTES); /* Burn the key from stack */+        secure_wipe_memory(block, BLAKE2B_BLOCKBYTES); /* Burn the key from stack */     }     return 0; }@@ -267,9 +267,9 @@     }      memcpy(out, buffer, S->outlen);-    burn(buffer, sizeof(buffer));-    burn(S->buf, sizeof(S->buf));-    burn(S->h, sizeof(S->h));+    secure_wipe_memory(buffer, sizeof(buffer));+    secure_wipe_memory(S->buf, sizeof(S->buf));+    secure_wipe_memory(S->h, sizeof(S->h));     return 0; } @@ -307,7 +307,7 @@     ret = blake2b_final(&S, out, outlen);  fail:-    burn(&S, sizeof(S));+    secure_wipe_memory(&S, sizeof(S));     return ret; } @@ -365,7 +365,7 @@         memcpy(out, out_buffer, toproduce);     } fail:-    burn(&blake_state, sizeof(blake_state));+    secure_wipe_memory(&blake_state, sizeof(blake_state));     return ret; #undef TRY }
+ phc-winner-argon2/src/blake2/blamka-round-ref.h view
@@ -0,0 +1,39 @@+#ifndef BLAKE_ROUND_MKA_H+#define BLAKE_ROUND_MKA_H++#include "blake2.h"+#include "blake2-impl.h"++/*designed by the Lyra PHC team */+static BLAKE2_INLINE uint64_t fBlaMka(uint64_t x, uint64_t y) {+    const uint64_t m = UINT64_C(0xFFFFFFFF);+    const uint64_t xy = (x & m) * (y & m);+    return x + y + 2 * xy;+}++#define G(a, b, c, d)                                                          \+    do {                                                                       \+        a = fBlaMka(a, b);                                                     \+        d = rotr64(d ^ a, 32);                                                 \+        c = fBlaMka(c, d);                                                     \+        b = rotr64(b ^ c, 24);                                                 \+        a = fBlaMka(a, b);                                                     \+        d = rotr64(d ^ a, 16);                                                 \+        c = fBlaMka(c, d);                                                     \+        b = rotr64(b ^ c, 63);                                                 \+    } while ((void)0, 0)++#define BLAKE2_ROUND_NOMSG(v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11,   \+                           v12, v13, v14, v15)                                 \+    do {                                                                       \+        G(v0, v4, v8, v12);                                                    \+        G(v1, v5, v9, v13);                                                    \+        G(v2, v6, v10, v14);                                                   \+        G(v3, v7, v11, v15);                                                   \+        G(v0, v5, v10, v15);                                                   \+        G(v1, v6, v11, v12);                                                   \+        G(v2, v7, v8, v13);                                                    \+        G(v3, v4, v9, v14);                                                    \+    } while ((void)0, 0)++#endif
phc-winner-argon2/src/core.c view
@@ -93,7 +93,6 @@         if (!*memory) {             return ARGON2_MEMORY_ALLOCATION_ERROR;         }-         return ARGON2_OK;     } else {         return ARGON2_MEMORY_ALLOCATION_ERROR;@@ -104,7 +103,7 @@ #if defined(_MSC_VER) && VC_GE_2005(_MSC_VER)     SecureZeroMemory(v, n); #elif defined memset_s-    memset_s(v, n);+    memset_s(v, n, 0, n); #elif defined(__OpenBSD__)     explicit_bzero(v, n); #else@@ -283,6 +282,8 @@                 if (l >= instance->threads) {                     rc = argon2_thread_join(thread[l - instance->threads]);                     if (rc) {+                        free(thr_data);+                        free(thread);                         return ARGON2_THREAD_FAIL;                     }                 }@@ -299,6 +300,8 @@                 rc = argon2_thread_create(&thread[l], &fill_segment_thr,                                           (void *)&thr_data[l]);                 if (rc) {+                    free(thr_data);+                    free(thread);                     return ARGON2_THREAD_FAIL;                 } @@ -417,7 +420,7 @@         return ARGON2_MEMORY_TOO_MUCH;     } -    if (context->m_cost < 8*context->lanes) {+    if (context->m_cost < 8 * context->lanes) {         return ARGON2_MEMORY_TOO_LITTLE;     } @@ -505,7 +508,7 @@     store32(&value, context->t_cost);     blake2b_update(&BlakeHash, (const uint8_t *)&value, sizeof(value)); -    store32(&value, ARGON2_VERSION_NUMBER);+    store32(&value, context->version);     blake2b_update(&BlakeHash, (const uint8_t *)&value, sizeof(value));      store32(&value, (uint32_t)type);@@ -572,7 +575,7 @@         if (ARGON2_OK != result) {             return result;         }-        memcpy(&(instance->memory), p, sizeof(instance->memory));+        instance->memory = (block *)p;     } else {         result = allocate_memory(&(instance->memory), instance->memory_blocks);         if (ARGON2_OK != result) {@@ -602,4 +605,3 @@      return ARGON2_OK; }-
+ phc-winner-argon2/src/core.h view
@@ -0,0 +1,219 @@+/*+ * Argon2 source code package+ *+ * Written by Daniel Dinu and Dmitry Khovratovich, 2015+ *+ * This work is licensed under a Creative Commons CC0 1.0 License/Waiver.+ *+ * You should have received a copy of the CC0 Public Domain Dedication along+ * with+ * this software. If not, see+ * <http://creativecommons.org/publicdomain/zero/1.0/>.+ */++#ifndef ARGON2_CORE_H+#define ARGON2_CORE_H++#include "argon2.h"++#if defined(_MSC_VER)+#define ALIGN(n) __declspec(align(16))+#elif defined(__GNUC__) || defined(__clang)+#define ALIGN(x) __attribute__((__aligned__(x)))+#else+#define ALIGN(x)+#endif++#define CONST_CAST(x) (x)(uintptr_t)++/*************************Argon2 internal+ * constants**************************************************/++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,++    /* 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;++/*****************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);++/*+ * 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_instance_t;++/*+ * 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;+} argon2_position_t;++/*Struct that holds the inputs for thread handling FillSegment*/+typedef struct Argon2_thread_data {+    argon2_instance_t *instance_ptr;+    argon2_position_t pos;+} argon2_thread_data;++/*************************Argon2 core+ * functions**************************************************/++/* Allocates memory to the given pointer+ * @param memory pointer to the pointer to the memory+ * @param m_cost number of blocks to allocate in the memory+ * @return ARGON2_OK if @memory is a valid pointer and memory is allocated+ */+int allocate_memory(block **memory, uint32_t m_cost);++/* Function that securely cleans the memory+ * @param mem Pointer to the memory+ * @param s Memory size in bytes+ */+void secure_wipe_memory(void *v, size_t n);++/* Clears memory+ * @param instance pointer to the current instance+ * @param clear_memory indicates if we clear the memory with zeros.+ */+void clear_memory(argon2_instance_t *instance, int clear);++/* Deallocates memory+ * @param memory pointer to the blocks+ */+void free_memory(block *memory);++/*+ * 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 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
phc-winner-argon2/src/encoding.c view
@@ -3,9 +3,10 @@ #include <string.h> #include <limits.h> #include "encoding.h"+#include "core.h" -#/*- * Example code for a decoder and encoder of "hash strings", with Argon2i+/*+ * Example code for a decoder and encoder of "hash strings", with Argon2  * parameters.  *  * This code comprises three sections:@@ -17,7 +18,7 @@  *   the relevant functions are made public (non-static) and be given  *   reasonable names to avoid collisions with other functions.  *- *   -- The second section is specific to Argon2i. It encodes and decodes+ *   -- The second section is specific to Argon2. It encodes and decodes  *   the parameters, salts and outputs. It does not compute the hash  *   itself.  *@@ -58,7 +59,7 @@  * Some macros for constant-time comparisons. These work over values in  * the 0..255 range. Returned value is 0x00 on "false", 0xFF on "true".  */-#define EQ(x, y) ((((0U-((unsigned)(x) ^ (unsigned)(y))) >> 8) & 0xFF) ^ 0xFF)+#define EQ(x, y) ((((0U - ((unsigned)(x) ^ (unsigned)(y))) >> 8) & 0xFF) ^ 0xFF) #define GT(x, y) ((((unsigned)(y) - (unsigned)(x)) >> 8) & 0xFF) #define GE(x, y) (GT(y, x) ^ 0xFF) #define LT(x, y) GT(y, x)@@ -122,11 +123,11 @@         acc_len += 8;         while (acc_len >= 6) {             acc_len -= 6;-            *dst++ = (char) b64_byte_to_char((acc >> acc_len) & 0x3F);+            *dst++ = (char)b64_byte_to_char((acc >> acc_len) & 0x3F);         }     }     if (acc_len > 0) {-        *dst++ = (char) b64_byte_to_char((acc << (6 - acc_len)) & 0x3F);+        *dst++ = (char)b64_byte_to_char((acc << (6 - acc_len)) & 0x3F);     }     *dst++ = 0;     return olen;@@ -224,16 +225,17 @@  /* ==================================================================== */ /*- * Code specific to Argon2i.+ * Code specific to Argon2.  *  * The code below applies the following format:  *- *  $argon2i$m=<num>,t=<num>,p=<num>[,keyid=<bin>][,data=<bin>][$<bin>[$<bin>]]+ *  $argon2<T>[$v=<num>]$m=<num>,t=<num>,p=<num>[,keyid=<bin>][,data=<bin>][$<bin>[$<bin>]]  *- * where <num> is a decimal integer (positive, fits in an 'unsigned long')- * and <bin> is Base64-encoded data (no '=' padding characters, no newline- * or whitespace). The "keyid" is a binary identifier for a key (up to 8- * bytes); "data" is associated data (up to 32 bytes). When the 'keyid'+ * where <T> is either 'd' or 'i', <num> is a decimal integer (positive, fits in+ * an 'unsigned long'), and <bin> is Base64-encoded data (no '=' padding+ * characters, no newline or whitespace).+ * The "keyid" is a binary identifier for a key (up to 8 bytes);+ * "data" is associated data (up to 32 bytes). When the 'keyid'  * (resp. the 'data') is empty, then it is ommitted from the output.  *  * The last two binary chunks (encoded in Base64) are, in that order,@@ -242,20 +244,19 @@  * The output length is always exactly 32 bytes.  */ -/*- * Decode an Argon2i hash string into the provided structure 'ctx'.- * Returned value is 1 on success, 0 on error.- */ int decode_string(argon2_context *ctx, const char *str, argon2_type type) {++/* check for prefix */ #define CC(prefix)                                                             \     do {                                                                       \         size_t cc_len = strlen(prefix);                                        \         if (strncmp(str, prefix, cc_len) != 0) {                               \-            return 0;                                                          \+            return ARGON2_DECODING_FAIL;                                       \         }                                                                      \         str += cc_len;                                                         \     } while ((void)0, 0) +/* prefix checking with supplied code */ #define CC_opt(prefix, code)                                                   \     do {                                                                       \         size_t cc_len = strlen(prefix);                                        \@@ -265,12 +266,13 @@         }                                                                      \     } while ((void)0, 0) +/* Decoding  prefix into decimal */ #define DECIMAL(x)                                                             \     do {                                                                       \         unsigned long dec_x;                                                   \         str = decode_decimal(str, &dec_x);                                     \         if (str == NULL) {                                                     \-            return 0;                                                          \+            return ARGON2_DECODING_FAIL;                                       \         }                                                                      \         (x) = dec_x;                                                           \     } while ((void)0, 0)@@ -280,7 +282,7 @@         size_t bin_len = (max_len);                                            \         str = from_base64(buf, &bin_len, str);                                 \         if (str == NULL || bin_len > UINT32_MAX) {                             \-            return 0;                                                          \+            return ARGON2_DECODING_FAIL;                                       \         }                                                                      \         (len) = (uint32_t)bin_len;                                             \     } while ((void)0, 0)@@ -288,16 +290,22 @@     size_t maxadlen = ctx->adlen;     size_t maxsaltlen = ctx->saltlen;     size_t maxoutlen = ctx->outlen;+    int validation_result;      ctx->adlen = 0;     ctx->saltlen = 0;     ctx->outlen = 0;+    ctx->pwdlen = 0;+     if (type == Argon2_i)         CC("$argon2i");     else if (type == Argon2_d)         CC("$argon2d");     else-        return 0;+        return ARGON2_INCORRECT_TYPE;+    ctx->version = ARGON2_VERSION_10;+    /* Reading the version number if the default is suppressed */+    CC_opt("$v=", DECIMAL(ctx->version));     CC("$m=");     DECIMAL(ctx->m_cost);     CC(",t=");@@ -306,75 +314,39 @@     DECIMAL(ctx->lanes);     ctx->threads = ctx->lanes; -    /*-     * Both m and t must be no more than 2^32-1. The tests below-     * use a shift by 30 bits to avoid a direct comparison with-     * 0xFFFFFFFF, which may trigger a spurious compiler warning-     * on machines where 'unsigned long' is a 32-bit type.-     */-    if (ctx->m_cost < 1 || (ctx->m_cost >> 30) > 3) {-        return 0;-    }-    if (ctx->t_cost < 1 || (ctx->t_cost >> 30) > 3) {-        return 0;-    }--    /*-     * The parallelism p must be between 1 and 255. The memory cost-     * parameter, expressed in kilobytes, must be at least 8 times-     * the value of p.-     */-    if (ctx->lanes < 1 || ctx->lanes > 255) {-        return 0;-    }-    if (ctx->m_cost < (ctx->lanes << 3)) {-        return 0;-    }-     CC_opt(",data=", BIN(ctx->ad, maxadlen, ctx->adlen));     if (*str == 0) {-        return 1;+        return ARGON2_OK;     }     CC("$");     BIN(ctx->salt, maxsaltlen, ctx->saltlen);-    if (ctx->saltlen < 8) {-        return 0;-    }     if (*str == 0) {-        return 1;+        return ARGON2_OK;     }     CC("$");     BIN(ctx->out, maxoutlen, ctx->outlen);-    if (ctx->outlen < 12) {-        return 0;+    validation_result = validate_inputs(ctx);+    if (validation_result != ARGON2_OK) {+        return validation_result;     }-    return *str == 0;-+    if (*str == 0) {+        return ARGON2_OK;+    } else {+        return ARGON2_DECODING_FAIL;+    } #undef CC #undef CC_opt #undef DECIMAL #undef BIN } -/*- * encode an argon2i 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 0.- *- * if pp->output_len is 0, then the hash string will be a salt string- * (no output). if pp->salt_len is also 0, then the string will be a- * parameter-only string (no salt and no output).- *- * on success, 1 is returned.- */ int encode_string(char *dst, size_t dst_len, argon2_context *ctx,                   argon2_type type) { #define SS(str)                                                                \     do {                                                                       \         size_t pp_len = strlen(str);                                           \         if (pp_len >= dst_len) {                                               \-            return 0;                                                          \+            return ARGON2_ENCODING_FAIL;                                       \         }                                                                      \         memcpy(dst, str, pp_len + 1);                                          \         dst += pp_len;                                                         \@@ -392,18 +364,24 @@     do {                                                                       \         size_t sb_len = to_base64(dst, dst_len, buf, len);                     \         if (sb_len == (size_t)-1) {                                            \-            return 0;                                                          \+            return ARGON2_ENCODING_FAIL;                                       \         }                                                                      \         dst += sb_len;                                                         \         dst_len -= sb_len;                                                     \     } while ((void)0, 0)      if (type == Argon2_i)-        SS("$argon2i$m=");+        SS("$argon2i$v=");     else if (type == Argon2_d)-        SS("$argon2d$m=");+        SS("$argon2d$v=");     else-        return 0;+        return ARGON2_ENCODING_FAIL;++    if (validate_inputs(ctx) != ARGON2_OK) {+        return validate_inputs(ctx);+    }+    SX(ctx->version);+    SS("$m=");     SX(ctx->m_cost);     SS(",t=");     SX(ctx->t_cost);@@ -416,19 +394,44 @@     }      if (ctx->saltlen == 0)-        return 1;+        return ARGON2_OK;      SS("$");     SB(ctx->salt, ctx->saltlen);      if (ctx->outlen == 0)-        return 1;+        return ARGON2_OK;      SS("$");     SB(ctx->out, ctx->outlen);-    return 1;+    return ARGON2_OK;  #undef SS #undef SX #undef SB }++size_t b64len(uint32_t len) {+    size_t olen = ((size_t)len / 3) << 2;++    switch (len % 3) {+    case 2:+        olen++;+    /* fall through */+    case 1:+        olen += 2;+        break;+    }++    return olen;+}++size_t numlen(uint32_t num) {+    size_t len = 1;+    while (num >= 10) {+        ++len;+        num = num / 10;+    }+    return len;+}+
+ phc-winner-argon2/src/encoding.h view
@@ -0,0 +1,40 @@+#ifndef ENCODING_H+#define ENCODING_H+#include "argon2.h"++#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)++/*+* 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.+*+* if ctx->outlen is 0, then the hash string will be a salt string+* (no output). if ctx->saltlen is also 0, then the string will be a+* parameter-only string (no salt and no output).+*+* on success, ARGON2_OK is returned.+*+* No other parameters are checked+*/+int encode_string(char *dst, size_t dst_len, argon2_context *ctx,+                  argon2_type type);++/*+* Decodes an Argon2 hash string into the provided structure 'ctx'.+* The fields ctx.saltlen, ctx.adlen, ctx.outlen set the maximal salt, ad, out+* length values that are allowed; invalid input string causes an error.+* 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
phc-winner-argon2/src/ref.c view
@@ -22,15 +22,55 @@ #include "blake2/blake2-impl.h" #include "blake2/blake2.h" + void fill_block(const block *prev_block, const block *ref_block,-                block *next_block) {+    block *next_block) {     block blockR, block_tmp;     unsigned i;      copy_block(&blockR, ref_block);     xor_block(&blockR, prev_block);     copy_block(&block_tmp, &blockR);+            /*Now blockR = ref_block + prev_block and bloc_tmp = ref_block + prev_block */+                /* Apply Blake2 on columns of 64-bit words: (0,1,...,15) , then+                (16,17,..31)... finally (112,113,...127) */+    for (i = 0; i < 8; ++i) {+        BLAKE2_ROUND_NOMSG(+            blockR.v[16 * i], blockR.v[16 * i + 1], blockR.v[16 * i + 2],+            blockR.v[16 * i + 3], blockR.v[16 * i + 4], blockR.v[16 * i + 5],+            blockR.v[16 * i + 6], blockR.v[16 * i + 7], blockR.v[16 * i + 8],+            blockR.v[16 * i + 9], blockR.v[16 * i + 10], blockR.v[16 * i + 11],+            blockR.v[16 * i + 12], blockR.v[16 * i + 13], blockR.v[16 * i + 14],+            blockR.v[16 * i + 15]);+    } +    /* Apply Blake2 on rows of 64-bit words: (0,1,16,17,...112,113), then+    (2,3,18,19,...,114,115).. finally (14,15,30,31,...,126,127) */+    for (i = 0; i < 8; i++) {+        BLAKE2_ROUND_NOMSG(+            blockR.v[2 * i], blockR.v[2 * i + 1], blockR.v[2 * i + 16],+            blockR.v[2 * i + 17], blockR.v[2 * i + 32], blockR.v[2 * i + 33],+            blockR.v[2 * i + 48], blockR.v[2 * i + 49], blockR.v[2 * i + 64],+            blockR.v[2 * i + 65], blockR.v[2 * i + 80], blockR.v[2 * i + 81],+            blockR.v[2 * i + 96], blockR.v[2 * i + 97], blockR.v[2 * i + 112],+            blockR.v[2 * i + 113]);+    }++    copy_block(next_block, &block_tmp);+    xor_block(next_block, &blockR);+}+++void fill_block_with_xor(const block *prev_block, const block *ref_block,+                block *next_block) {+    block blockR, block_tmp;+    unsigned i;++    copy_block(&blockR, ref_block);+    xor_block(&blockR, prev_block);+    copy_block(&block_tmp, &blockR);+    xor_block(&block_tmp, next_block); /*Saving the next block contents for XOR over*/+    /*Now blockR = ref_block + prev_block and bloc_tmp = ref_block + prev_block + next_block*/     /* Apply Blake2 on columns of 64-bit words: (0,1,...,15) , then        (16,17,..31)... finally (112,113,...127) */     for (i = 0; i < 8; ++i) {@@ -62,12 +102,11 @@ void generate_addresses(const argon2_instance_t *instance,                         const argon2_position_t *position,                         uint64_t *pseudo_rands) {-    block zero_block, input_block, address_block;+    block zero_block, input_block, address_block,tmp_block;     uint32_t i;      init_block_value(&zero_block, 0);     init_block_value(&input_block, 0);-    init_block_value(&address_block, 0);      if (instance != NULL && position != NULL) {         input_block.v[0] = position->pass;@@ -80,8 +119,10 @@         for (i = 0; i < instance->segment_length; ++i) {             if (i % ARGON2_ADDRESSES_IN_BLOCK == 0) {                 input_block.v[6]++;-                fill_block(&zero_block, &input_block, &address_block);-                fill_block(&zero_block, &address_block, &address_block);+                init_block_value(&tmp_block, 0);+                init_block_value(&address_block, 0);+                fill_block_with_xor(&zero_block, &input_block, &tmp_block);+                fill_block_with_xor(&zero_block, &tmp_block, &address_block);             }              pseudo_rands[i] = address_block.v[i % ARGON2_ADDRESSES_IN_BLOCK];@@ -169,7 +210,18 @@         ref_block =             instance->memory + instance->lane_length * ref_lane + ref_index;         curr_block = instance->memory + curr_offset;-        fill_block(instance->memory + prev_offset, ref_block, curr_block);+        if (ARGON2_VERSION_10 == instance->version) {+            /* version 1.2.1 and earlier: overwrite, not XOR */+            fill_block(instance->memory + prev_offset, ref_block, curr_block);+        } else {+            if(0 == position.pass) {+                fill_block(instance->memory + prev_offset, ref_block,+                           curr_block);+            } else {+                fill_block_with_xor(instance->memory + prev_offset, ref_block,+                                    curr_block);+            }+        }     }      free(pseudo_rands);
+ phc-winner-argon2/src/ref.h view
@@ -0,0 +1,51 @@+/*+ * Argon2 source code package+ *+ * Written by Daniel Dinu and Dmitry Khovratovich, 2015+ *+ * This work is licensed under a Creative Commons CC0 1.0 License/Waiver.+ *+ * You should have received a copy of the CC0 Public Domain Dedication along+ * with+ * this software. If not, see+ * <http://creativecommons.org/publicdomain/zero/1.0/>.+ */++#ifndef ARGON2_REF_H+#define ARGON2_REF_H++#include "core.h"++/*+ * Function fills a new memory block by XORing over @next_block. @next_block must be initialized+ * @param prev_block Pointer to the previous block+ * @param ref_block Pointer to the reference block+ * @param next_block Pointer to the block to be constructed+ * @pre all block pointers must be valid+ */+void fill_block_with_xor(const block *prev_block, const block *ref_block,+                block *next_block);++/* LEGACY CODE: version 1.2.1 and earlier+* Function fills a new memory block by overwriting @next_block. +* @param prev_block Pointer to the previous block+* @param ref_block Pointer to the reference block+* @param next_block Pointer to the block to be constructed+* @pre all block pointers must be valid+*/+void fill_block(const block *prev_block, const block *ref_block,+    block *next_block);++/*+ * Generate pseudo-random values to reference blocks in the segment and puts+ * them into the array+ * @param instance Pointer to the current instance+ * @param position Pointer to the current position+ * @param pseudo_rands Pointer to the array of 64-bit values+ * @pre pseudo_rands must point to @a instance->segment_length allocated values+ */+void generate_addresses(const argon2_instance_t *instance,+                        const argon2_position_t *position,+                        uint64_t *pseudo_rands);++#endif /* ARGON2_REF_H */
phc-winner-argon2/src/thread.c view
@@ -1,6 +1,6 @@ #include "thread.h" #if defined(_WIN32)-#include <Windows.h>+#include <windows.h> #endif  int argon2_thread_create(argon2_thread_handle_t *handle,
+ phc-winner-argon2/src/thread.h view
@@ -0,0 +1,46 @@+#ifndef ARGON2_THREAD_H+#define ARGON2_THREAD_H+/*+        Here we implement an abstraction layer for the simpĺe requirements+        of the Argon2 code. We only require 3 primitives---thread creation,+        joining, and termination---so full emulation of the pthreads API+        is unwarranted. Currently we wrap pthreads and Win32 threads.++        The API defines 2 types: the function pointer type,+   argon2_thread_func_t,+        and the type of the thread handle---argon2_thread_handle_t.+*/+#if defined(_WIN32)+#include <process.h>+typedef unsigned(__stdcall *argon2_thread_func_t)(void *);+typedef uintptr_t argon2_thread_handle_t;+#else+#include <pthread.h>+typedef void *(*argon2_thread_func_t)(void *);+typedef pthread_t argon2_thread_handle_t;+#endif++/* Creates a thread+ * @param handle pointer to a thread handle, which is the output of this+ * function. Must not be NULL.+ * @param func A function pointer for the thread's entry point. Must not be+ * NULL.+ * @param args Pointer that is passed as an argument to @func. May be NULL.+ * @return 0 if @handle and @func are valid pointers and a thread is successfuly+ * created.+ */+int argon2_thread_create(argon2_thread_handle_t *handle,+                         argon2_thread_func_t func, void *args);++/* Waits for a thread to terminate+ * @param handle Handle to a thread created with argon2_thread_create.+ * @return 0 if @handle is a valid handle, and joining completed successfully.+*/+int argon2_thread_join(argon2_thread_handle_t handle);++/* Terminate the current thread. Must be run inside a thread created by+ * argon2_thread_create.+*/+void argon2_thread_exit(void);++#endif
src/Crypto/Argon2.hs view
@@ -117,9 +117,9 @@ -- will be throw. data Argon2Exception   = -- | The length of the supplied password is outside the range supported by @libargon2@.-    Argon2PasswordLengthOutOfRange !Word64 -- ^ The erroneous length.+    Argon2PasswordLengthOutOfRange !CSize -- ^ The erroneous length.   | -- | The length of the supplied salt is outside the range supported by @libargon2@.-    Argon2SaltLengthOutOfRange !Word64 -- ^ The erroneous length.+    Argon2SaltLengthOutOfRange !CSize -- ^ The erroneous length.   | -- | Either too much or too little memory was requested via 'hashMemory'.     Argon2MemoryUseOutOfRange !Word32 -- ^ The erroneous 'hashMemory' value.   | -- | Either too few or too many iterations were requested via 'hashIterations'.@@ -132,7 +132,7 @@  instance Exception Argon2Exception -type Argon2Encoded = Word32 -> Word32 -> Word32 -> CString -> Word64 -> CString -> Word64 -> Word64 -> CString -> Word64 -> IO Int32+type Argon2Encoded = Word32 -> Word32 -> Word32 -> CString -> CSize -> CString -> CSize -> CSize -> CString -> CSize -> IO Int32  hashEncoded' :: HashOptions              -> BS.ByteString@@ -143,10 +143,12 @@ hashEncoded' options@HashOptions{..} password salt argon2i argon2d =   do let saltLen = fromIntegral (BS.length salt)          passwordLen = fromIntegral (BS.length password)-         outLen =-           (BS.length salt * 4 + 32 * 4 +-            length ("$argon2x$m=,t=,p=$$" :: String) +-            3 * 3)+     outLen <- fmap fromIntegral $ FFI.argon2_encodedlen+                                              hashIterations+                                              hashMemory+                                              hashParallelism+                                              saltLen+                                              hashlen      out <- mallocBytes outLen      res <-        BS.useAsCString password $@@ -159,15 +161,16 @@                   password'                   passwordLen                   salt'-                  saltLen-                  64+                  (fromIntegral saltLen)+                  (fromIntegral hashlen)                   out                   (fromIntegral outLen)      handleSuccessCode res options password salt      fmap T.decodeUtf8 (BS.packCString out)   where argon2 = variant argon2i argon2d hashVariant+        hashlen = 64 -type Argon2Unencoded = Word32 -> Word32 -> Word32 -> CString -> Word64 -> CString -> Word64 -> CString -> Word64 -> IO Int32+type Argon2Unencoded = Word32 -> Word32 -> Word32 -> CString -> CSize -> CString -> CSize -> CString -> CSize -> IO Int32  hash' :: HashOptions       -> BS.ByteString@@ -195,7 +198,7 @@                   out                   (fromIntegral outLen)      handleSuccessCode res options password salt-     BS.packCString out+     BS.packCStringLen (out, outLen)   where argon2 = variant argon2i argon2d hashVariant  handleSuccessCode :: Int32
src/Crypto/Argon2/FFI.hsc view
@@ -9,17 +9,19 @@ import Foreign import Foreign.C -foreign import ccall unsafe "argon2.h argon2i_hash_encoded" argon2i_hash_encoded :: (#type const uint32_t) -> (#type const uint32_t) -> (#type const uint32_t) -> Ptr a -> (#type const size_t) -> Ptr b -> (# type const size_t) -> (#type const size_t) -> CString -> (#type const size_t) -> IO (#type int)+foreign import ccall unsafe "argon2.h argon2i_hash_encoded" argon2i_hash_encoded :: (#type const uint32_t) -> (#type const uint32_t) -> (#type const uint32_t) -> Ptr a -> CSize -> Ptr b -> CSize -> CSize -> CString -> CSize -> IO (#type int) -foreign import ccall unsafe "argon2.h argon2i_hash_raw" argon2i_hash_raw :: (#type const uint32_t) -> (#type const uint32_t) -> (#type const uint32_t) -> Ptr a -> (#type const size_t) -> Ptr b -> (#type size_t) -> Ptr c -> (#type const size_t) -> IO (#type int)+foreign import ccall unsafe "argon2.h argon2i_hash_raw" argon2i_hash_raw :: (#type const uint32_t) -> (#type const uint32_t) -> (#type const uint32_t) -> Ptr a -> CSize -> Ptr b -> CSize -> Ptr c -> CSize -> IO (#type int) -foreign import ccall unsafe "argon2.h argon2d_hash_encoded" argon2d_hash_encoded :: (#type const uint32_t) -> (#type const uint32_t) -> (#type const uint32_t) -> Ptr a -> (#type const size_t) -> Ptr b -> (# type const size_t) -> (#type const size_t) -> CString -> (#type const size_t) -> IO (#type int)+foreign import ccall unsafe "argon2.h argon2d_hash_encoded" argon2d_hash_encoded :: (#type const uint32_t) -> (#type const uint32_t) -> (#type const uint32_t) -> Ptr a -> CSize -> Ptr b -> CSize -> CSize -> CString -> CSize -> IO (#type int) -foreign import ccall unsafe "argon2.h argon2d_hash_raw" argon2d_hash_raw :: (#type const uint32_t) -> (#type const uint32_t) -> (#type const uint32_t) -> Ptr a -> (#type const size_t) -> Ptr b -> (#type size_t) -> Ptr c -> (#type const size_t) -> IO (#type int)+foreign import ccall unsafe "argon2.h argon2d_hash_raw" argon2d_hash_raw :: (#type const uint32_t) -> (#type const uint32_t) -> (#type const uint32_t) -> Ptr a -> CSize -> Ptr b -> CSize -> Ptr c -> CSize -> IO (#type int) -foreign import ccall unsafe "argon2.h argon2i_verify" argon2i_verify :: CString -> Ptr a -> (#type const size_t) -> IO (#type int)+foreign import ccall unsafe "argon2.h argon2i_verify" argon2i_verify :: CString -> Ptr a -> CSize -> IO (#type int) -foreign import ccall unsafe "argon2.h argon2d_verify" argon2d_verify :: CString -> Ptr a -> (#type const size_t) -> IO (#type int)+foreign import ccall unsafe "argon2.h argon2d_verify" argon2d_verify :: CString -> Ptr a -> CSize -> IO (#type int)++foreign import ccall unsafe "argon2.h argon2_encodedlen" argon2_encodedlen :: (#type const uint32_t) -> (#type const uint32_t) -> (#type const uint32_t) -> (#type const uint32_t) -> (#type const uint32_t) -> IO CSize  pattern ARGON2_OK = (#const ARGON2_OK) pattern ARGON2_OUTPUT_PTR_NULL = (#const ARGON2_OUTPUT_PTR_NULL)