From 28a5740c3754f6916416e7399c4b27b51a97928e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Adrien=20B=C3=A9raud?= <adrien.beraud@savoirfairelinux.com>
Date: Tue, 25 Oct 2016 15:55:33 -0400
Subject: [PATCH] argon2: bump source

---
 src/argon2/argon2.c                  | 75 +++++++++++++++++++++++-----
 src/argon2/argon2.h                  | 74 ++++++++++++++++++++++++---
 src/argon2/blake2/blake2-impl.h      | 23 +++++++--
 src/argon2/blake2/blake2.h           | 17 +++++++
 src/argon2/blake2/blake2b.c          | 31 +++++++++---
 src/argon2/blake2/blamka-round-opt.h | 17 +++++++
 src/argon2/blake2/blamka-round-ref.h | 17 +++++++
 src/argon2/core.c                    | 59 +++++++++++-----------
 src/argon2/core.h                    | 18 ++++---
 src/argon2/encoding.c                | 47 +++++++++++++----
 src/argon2/encoding.h                | 17 +++++++
 src/argon2/opt.c                     | 23 ++++++---
 src/argon2/opt.h                     | 18 ++++---
 src/argon2/ref.c                     | 23 ++++++---
 src/argon2/ref.h                     | 18 ++++---
 src/argon2/thread.c                  | 17 +++++++
 src/argon2/thread.h                  | 17 +++++++
 17 files changed, 402 insertions(+), 109 deletions(-)

diff --git a/src/argon2/argon2.c b/src/argon2/argon2.c
index 0fab3116..52fbae9b 100644
--- a/src/argon2/argon2.c
+++ b/src/argon2/argon2.c
@@ -1,14 +1,18 @@
 /*
- * Argon2 source code package
+ * Argon2 reference source code package - reference C implementations
  *
- * Written by Daniel Dinu and Dmitry Khovratovich, 2015
+ * Copyright 2015
+ * Daniel Dinu, Dmitry Khovratovich, Jean-Philippe Aumasson, and Samuel Neves
  *
- * This work is licensed under a Creative Commons CC0 1.0 License/Waiver.
+ * 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:
  *
- * 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/>.
+ * - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0
+ * - Apache 2.0        : http://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.
  */
 
 #include <string.h>
@@ -19,6 +23,18 @@
 #include "encoding.h"
 #include "core.h"
 
+const char *argon2_type2string(argon2_type type, int uppercase) {
+    switch (type) {
+        case Argon2_d:
+            return uppercase ? "Argon2d" : "argon2d";
+        case Argon2_i:
+            return uppercase ? "Argon2i" : "argon2i";
+        case Argon2_id:
+            return uppercase ? "Argon2id" : "argon2id";
+    }
+
+    return NULL;
+}
 
 int argon2_ctx(argon2_context *context, argon2_type type) {
     /* 1. Validate all inputs */
@@ -30,7 +46,7 @@ int argon2_ctx(argon2_context *context, argon2_type type) {
         return result;
     }
 
-    if (Argon2_d != type && Argon2_i != type) {
+    if (Argon2_d != type && Argon2_i != type && Argon2_id != type) {
         return ARGON2_INCORRECT_TYPE;
     }
 
@@ -81,7 +97,7 @@ 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;
@@ -188,6 +204,26 @@ int argon2d_hash_raw(const uint32_t t_cost, const uint32_t m_cost,
                        hash, hashlen, NULL, 0, Argon2_d, ARGON2_VERSION_NUMBER);
 }
 
+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) {
+
+    return argon2_hash(t_cost, m_cost, parallelism, pwd, pwdlen, salt, saltlen,
+                       NULL, hashlen, encoded, encodedlen, Argon2_id,
+                       ARGON2_VERSION_NUMBER);
+}
+
+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) {
+    return argon2_hash(t_cost, m_cost, parallelism, pwd, pwdlen, salt, saltlen,
+                       hash, hashlen, NULL, 0, Argon2_id,
+                       ARGON2_VERSION_NUMBER);
+}
+
 static int argon2_compare(const uint8_t *b1, const uint8_t *b2, size_t len) {
     size_t i;
     uint8_t d = 0U;
@@ -279,6 +315,11 @@ int argon2d_verify(const char *encoded, const void *pwd, const size_t pwdlen) {
     return argon2_verify(encoded, pwd, pwdlen, Argon2_d);
 }
 
+int argon2id_verify(const char *encoded, const void *pwd, const size_t pwdlen) {
+
+    return argon2_verify(encoded, pwd, pwdlen, Argon2_id);
+}
+
 int argon2d_ctx(argon2_context *context) {
     return argon2_ctx(context, Argon2_d);
 }
@@ -287,6 +328,10 @@ int argon2i_ctx(argon2_context *context) {
     return argon2_ctx(context, Argon2_i);
 }
 
+int argon2id_ctx(argon2_context *context) {
+    return argon2_ctx(context, Argon2_id);
+}
+
 int argon2_verify_ctx(argon2_context *context, const char *hash,
                       argon2_type type) {
     int result;
@@ -311,6 +356,10 @@ int argon2i_verify_ctx(argon2_context *context, const char *hash) {
     return argon2_verify_ctx(context, hash, Argon2_i);
 }
 
+int argon2id_verify_ctx(argon2_context *context, const char *hash) {
+    return argon2_verify_ctx(context, hash, Argon2_id);
+}
+
 const char *argon2_error_message(int error_code) {
     switch (error_code) {
     case ARGON2_OK:
@@ -391,8 +440,8 @@ const char *argon2_error_message(int 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;
+                         uint32_t saltlen, uint32_t hashlen, argon2_type type) {
+  return strlen("$$v=$m=,t=,p=$$") + strlen(argon2_type2string(type, 0)) +
+         numlen(t_cost) + numlen(m_cost) + numlen(parallelism) +
+         b64len(saltlen) + b64len(hashlen) + numlen(ARGON2_VERSION_NUMBER) + 1;
 }
diff --git a/src/argon2/argon2.h b/src/argon2/argon2.h
index d4c7d5b4..46075786 100644
--- a/src/argon2/argon2.h
+++ b/src/argon2/argon2.h
@@ -1,13 +1,18 @@
 /*
- * Argon2 source code package
+ * Argon2 reference source code package - reference C implementations
  *
- * Written by Daniel Dinu and Dmitry Khovratovich, 2015
+ * Copyright 2015
+ * Daniel Dinu, Dmitry Khovratovich, Jean-Philippe Aumasson, and Samuel Neves
  *
- * This work is licensed under a Creative Commons CC0 1.0 License/Waiver.
+ * 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:
  *
- * 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/>.
+ * - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0
+ * - Apache 2.0        : http://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_H
@@ -24,6 +29,8 @@ extern "C" {
 /* 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
@@ -204,7 +211,11 @@ typedef struct Argon2_Context {
 } argon2_context;
 
 /* Argon2 primitive type */
-typedef enum Argon2_type { Argon2_d = 0, Argon2_i = 1 } argon2_type;
+typedef enum Argon2_type {
+  Argon2_d = 0,
+  Argon2_i = 1,
+  Argon2_id = 2
+} argon2_type;
 
 /* Version of the algorithm */
 typedef enum Argon2_version {
@@ -213,6 +224,14 @@ typedef enum Argon2_version {
     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);
+
 /*
  * Function that performs memory-hard hashing with certain degree of parallelism
  * @param  context  Pointer to the Argon2 internal structure
@@ -278,6 +297,21 @@ ARGON2_PUBLIC int argon2d_hash_raw(const uint32_t t_cost, const uint32_t m_cost,
                                    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,
@@ -300,6 +334,9 @@ ARGON2_PUBLIC int argon2i_verify(const char *encoded, const void *pwd,
 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);
@@ -324,6 +361,17 @@ ARGON2_PUBLIC int argon2d_ctx(argon2_context *context);
  */
 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
@@ -342,6 +390,16 @@ ARGON2_PUBLIC int argon2d_verify_ctx(argon2_context *context, const char *hash);
  */
 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);
@@ -363,7 +421,7 @@ ARGON2_PUBLIC const char *argon2_error_message(int error_code);
  */
 ARGON2_PUBLIC size_t argon2_encodedlen(uint32_t t_cost, uint32_t m_cost,
                                        uint32_t parallelism, uint32_t saltlen,
-                                       uint32_t hashlen);
+                                       uint32_t hashlen, argon2_type type);
 
 #if defined(__cplusplus)
 }
diff --git a/src/argon2/blake2/blake2-impl.h b/src/argon2/blake2/blake2-impl.h
index 115a192d..083bef48 100644
--- a/src/argon2/blake2/blake2-impl.h
+++ b/src/argon2/blake2/blake2-impl.h
@@ -1,3 +1,20 @@
+/*
+ * 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 : http://creativecommons.org/publicdomain/zero/1.0
+ * - Apache 2.0        : http://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 PORTABLE_BLAKE2_IMPL_H
 #define PORTABLE_BLAKE2_IMPL_H
 
@@ -134,10 +151,6 @@ static BLAKE2_INLINE uint64_t rotr64(const uint64_t w, const unsigned c) {
     return (w >> c) | (w << (64 - c));
 }
 
-/* prevents compiler optimizing out memset() */
-static BLAKE2_INLINE void burn(void *v, size_t n) {
-    static void *(*const volatile memset_v)(void *, int, size_t) = &memset;
-    memset_v(v, 0, n);
-}
+void secure_wipe_memory(void *v, size_t n);
 
 #endif
diff --git a/src/argon2/blake2/blake2.h b/src/argon2/blake2/blake2.h
index d28d9a79..0168e0ff 100644
--- a/src/argon2/blake2/blake2.h
+++ b/src/argon2/blake2/blake2.h
@@ -1,3 +1,20 @@
+/*
+ * 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 : http://creativecommons.org/publicdomain/zero/1.0
+ * - Apache 2.0        : http://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 PORTABLE_BLAKE2_H
 #define PORTABLE_BLAKE2_H
 
diff --git a/src/argon2/blake2/blake2b.c b/src/argon2/blake2/blake2b.c
index 28dec868..603bc819 100644
--- a/src/argon2/blake2/blake2b.c
+++ b/src/argon2/blake2/blake2b.c
@@ -1,3 +1,20 @@
+/*
+ * 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 : http://creativecommons.org/publicdomain/zero/1.0
+ * - Apache 2.0        : http://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.
+ */
+
 #include <stdint.h>
 #include <string.h>
 #include <stdio.h>
@@ -44,7 +61,7 @@ static BLAKE2_INLINE void blake2b_increment_counter(blake2b_state *S,
 }
 
 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 +157,7 @@ int blake2b_init_key(blake2b_state *S, size_t outlen, const void *key,
         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 +284,9 @@ int blake2b_final(blake2b_state *S, void *out, size_t outlen) {
     }
 
     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 +324,7 @@ int blake2b(void *out, size_t outlen, const void *in, size_t inlen,
     ret = blake2b_final(&S, out, outlen);
 
 fail:
-    burn(&S, sizeof(S));
+    secure_wipe_memory(&S, sizeof(S));
     return ret;
 }
 
@@ -365,7 +382,7 @@ int blake2b_long(void *pout, size_t outlen, const void *in, size_t inlen) {
         memcpy(out, out_buffer, toproduce);
     }
 fail:
-    burn(&blake_state, sizeof(blake_state));
+    secure_wipe_memory(&blake_state, sizeof(blake_state));
     return ret;
 #undef TRY
 }
diff --git a/src/argon2/blake2/blamka-round-opt.h b/src/argon2/blake2/blamka-round-opt.h
index 44845a54..577e1d0c 100644
--- a/src/argon2/blake2/blamka-round-opt.h
+++ b/src/argon2/blake2/blamka-round-opt.h
@@ -1,3 +1,20 @@
+/*
+ * 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 : http://creativecommons.org/publicdomain/zero/1.0
+ * - Apache 2.0        : http://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 BLAKE_ROUND_MKA_OPT_H
 #define BLAKE_ROUND_MKA_OPT_H
 
diff --git a/src/argon2/blake2/blamka-round-ref.h b/src/argon2/blake2/blamka-round-ref.h
index f497e10c..db9864d7 100644
--- a/src/argon2/blake2/blamka-round-ref.h
+++ b/src/argon2/blake2/blamka-round-ref.h
@@ -1,3 +1,20 @@
+/*
+ * 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 : http://creativecommons.org/publicdomain/zero/1.0
+ * - Apache 2.0        : http://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 BLAKE_ROUND_MKA_H
 #define BLAKE_ROUND_MKA_H
 
diff --git a/src/argon2/core.c b/src/argon2/core.c
index 278d36c8..ed02494a 100644
--- a/src/argon2/core.c
+++ b/src/argon2/core.c
@@ -1,14 +1,18 @@
 /*
- * Argon2 source code package
+ * Argon2 reference source code package - reference C implementations
  *
- * Written by Daniel Dinu and Dmitry Khovratovich, 2015
+ * Copyright 2015
+ * Daniel Dinu, Dmitry Khovratovich, Jean-Philippe Aumasson, and Samuel Neves
  *
- * This work is licensed under a Creative Commons CC0 1.0 License/Waiver.
+ * 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:
  *
- * 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/>.
+ * - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0
+ * - Apache 2.0        : http://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.
  */
 
 /*For memory wiping*/
@@ -252,26 +256,28 @@ int fill_memory_blocks(argon2_instance_t *instance) {
     uint32_t r, s;
     argon2_thread_handle_t *thread = NULL;
     argon2_thread_data *thr_data = NULL;
+    int rc = ARGON2_OK;
 
     if (instance == NULL || instance->lanes == 0) {
-        return ARGON2_THREAD_FAIL;
+        rc = ARGON2_THREAD_FAIL;
+        goto fail;
     }
 
     /* 1. Allocating space for threads */
     thread = calloc(instance->lanes, sizeof(argon2_thread_handle_t));
     if (thread == NULL) {
-        return ARGON2_MEMORY_ALLOCATION_ERROR;
+        rc = ARGON2_MEMORY_ALLOCATION_ERROR;
+        goto fail;
     }
 
     thr_data = calloc(instance->lanes, sizeof(argon2_thread_data));
     if (thr_data == NULL) {
-        free(thread);
-        return ARGON2_MEMORY_ALLOCATION_ERROR;
+        rc = ARGON2_MEMORY_ALLOCATION_ERROR;
+        goto fail;
     }
 
     for (r = 0; r < instance->passes; ++r) {
         for (s = 0; s < ARGON2_SYNC_POINTS; ++s) {
-            int rc;
             uint32_t l;
 
             /* 2. Calling threads */
@@ -280,11 +286,9 @@ int fill_memory_blocks(argon2_instance_t *instance) {
 
                 /* 2.1 Join a thread if limit is exceeded */
                 if (l >= instance->threads) {
-                    rc = argon2_thread_join(thread[l - instance->threads]);
-                    if (rc) {
-                        free(thr_data);
-                        free(thread);
-                        return ARGON2_THREAD_FAIL;
+                    if (argon2_thread_join(thread[l - instance->threads])) {
+                        rc = ARGON2_THREAD_FAIL;
+                        goto fail;
                     }
                 }
 
@@ -297,12 +301,10 @@ int fill_memory_blocks(argon2_instance_t *instance) {
                     instance; /* preparing the thread input */
                 memcpy(&(thr_data[l].pos), &position,
                        sizeof(argon2_position_t));
-                rc = argon2_thread_create(&thread[l], &fill_segment_thr,
-                                          (void *)&thr_data[l]);
-                if (rc) {
-                    free(thr_data);
-                    free(thread);
-                    return ARGON2_THREAD_FAIL;
+                if (argon2_thread_create(&thread[l], &fill_segment_thr,
+                                         (void *)&thr_data[l])) {
+                    rc = ARGON2_THREAD_FAIL;
+                    goto fail;
                 }
 
                 /* fill_segment(instance, position); */
@@ -312,9 +314,9 @@ int fill_memory_blocks(argon2_instance_t *instance) {
             /* 3. Joining remaining threads */
             for (l = instance->lanes - instance->threads; l < instance->lanes;
                  ++l) {
-                rc = argon2_thread_join(thread[l]);
-                if (rc) {
-                    return ARGON2_THREAD_FAIL;
+                if (argon2_thread_join(thread[l])) {
+                    rc = ARGON2_THREAD_FAIL;
+                    goto fail;
                 }
             }
         }
@@ -324,13 +326,14 @@ int fill_memory_blocks(argon2_instance_t *instance) {
 #endif
     }
 
+fail:
     if (thread != NULL) {
         free(thread);
     }
     if (thr_data != NULL) {
         free(thr_data);
     }
-    return ARGON2_OK;
+    return rc;
 }
 
 int validate_inputs(const argon2_context *context) {
@@ -575,7 +578,7 @@ int initialize(argon2_instance_t *instance, argon2_context *context) {
         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) {
diff --git a/src/argon2/core.h b/src/argon2/core.h
index e1e70faf..f5c2d437 100644
--- a/src/argon2/core.h
+++ b/src/argon2/core.h
@@ -1,14 +1,18 @@
 /*
- * Argon2 source code package
+ * Argon2 reference source code package - reference C implementations
  *
- * Written by Daniel Dinu and Dmitry Khovratovich, 2015
+ * Copyright 2015
+ * Daniel Dinu, Dmitry Khovratovich, Jean-Philippe Aumasson, and Samuel Neves
  *
- * This work is licensed under a Creative Commons CC0 1.0 License/Waiver.
+ * 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:
  *
- * 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/>.
+ * - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0
+ * - Apache 2.0        : http://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
diff --git a/src/argon2/encoding.c b/src/argon2/encoding.c
index 5e656217..2fc8d547 100644
--- a/src/argon2/encoding.c
+++ b/src/argon2/encoding.c
@@ -1,3 +1,20 @@
+/*
+ * 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 : http://creativecommons.org/publicdomain/zero/1.0
+ * - Apache 2.0        : http://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.
+ */
+
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -291,21 +308,26 @@ int decode_string(argon2_context *ctx, const char *str, argon2_type type) {
     size_t maxsaltlen = ctx->saltlen;
     size_t maxoutlen = ctx->outlen;
     int validation_result;
+    const char* type_string;
 
     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
+    /* We should start with the argon2_type we are using */
+    CC("$");
+    type_string = argon2_type2string(type, 0);
+    if (type_string) {
+        CC(type_string);
+    } else {
         return ARGON2_INCORRECT_TYPE;
-    ctx->version = ARGON2_VERSION_10;
+    }
+
     /* Reading the version number if the default is suppressed */
+    ctx->version = ARGON2_VERSION_10;
     CC_opt("$v=", DECIMAL(ctx->version));
+
     CC("$m=");
     DECIMAL(ctx->m_cost);
     CC(",t=");
@@ -370,16 +392,19 @@ int encode_string(char *dst, size_t dst_len, argon2_context *ctx,
         dst_len -= sb_len;                                                     \
     } while ((void)0, 0)
 
-    if (type == Argon2_i)
-        SS("$argon2i$v=");
-    else if (type == Argon2_d)
-        SS("$argon2d$v=");
-    else
+    const char* type_string = argon2_type2string(type, 0);
+    SS("$");
+    if (type_string) {
+        SS(type_string);
+    } else {
         return ARGON2_ENCODING_FAIL;
+    }
 
     if (validate_inputs(ctx) != ARGON2_OK) {
         return validate_inputs(ctx);
     }
+
+    SS("$v=");
     SX(ctx->version);
     SS("$m=");
     SX(ctx->m_cost);
diff --git a/src/argon2/encoding.h b/src/argon2/encoding.h
index 8671f6b3..f652dfa0 100644
--- a/src/argon2/encoding.h
+++ b/src/argon2/encoding.h
@@ -1,3 +1,20 @@
+/*
+ * 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 : http://creativecommons.org/publicdomain/zero/1.0
+ * - Apache 2.0        : http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * You should have received a copy of both of these licenses along with this
+ * software. If not, they may be obtained at the above URLs.
+ */
+
 #ifndef ENCODING_H
 #define ENCODING_H
 #include "argon2.h"
diff --git a/src/argon2/opt.c b/src/argon2/opt.c
index 2ba467d5..ab2cb6a2 100644
--- a/src/argon2/opt.c
+++ b/src/argon2/opt.c
@@ -1,14 +1,18 @@
 /*
- * Argon2 source code package
+ * Argon2 reference source code package - reference C implementations
  *
- * Written by Daniel Dinu and Dmitry Khovratovich, 2015
+ * Copyright 2015
+ * Daniel Dinu, Dmitry Khovratovich, Jean-Philippe Aumasson, and Samuel Neves
  *
- * This work is licensed under a Creative Commons CC0 1.0 License/Waiver.
+ * 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:
  *
- * 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/>.
+ * - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0
+ * - Apache 2.0        : http://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.
  */
 
 #include <stdint.h>
@@ -135,7 +139,10 @@ void fill_segment(const argon2_instance_t *instance,
         return;
     }
 
-    data_independent_addressing = (instance->type == Argon2_i);
+    data_independent_addressing =
+        (instance->type == Argon2_i) ||
+        (instance->type == Argon2_id && (position.pass == 0) &&
+         (position.slice < ARGON2_SYNC_POINTS / 2));
 
     pseudo_rands =
         (uint64_t *)malloc(sizeof(uint64_t) * instance->segment_length);
diff --git a/src/argon2/opt.h b/src/argon2/opt.h
index 49660c29..caa7ea9a 100644
--- a/src/argon2/opt.h
+++ b/src/argon2/opt.h
@@ -1,14 +1,18 @@
 /*
- * Argon2 source code package
+ * Argon2 reference source code package - reference C implementations
  *
- * Written by Daniel Dinu and Dmitry Khovratovich, 2015
+ * Copyright 2015
+ * Daniel Dinu, Dmitry Khovratovich, Jean-Philippe Aumasson, and Samuel Neves
  *
- * This work is licensed under a Creative Commons CC0 1.0 License/Waiver.
+ * 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:
  *
- * 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/>.
+ * - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0
+ * - Apache 2.0        : http://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_OPT_H
diff --git a/src/argon2/ref.c b/src/argon2/ref.c
index 9ee61012..0b086c38 100644
--- a/src/argon2/ref.c
+++ b/src/argon2/ref.c
@@ -1,14 +1,18 @@
 /*
- * Argon2 source code package
+ * Argon2 reference source code package - reference C implementations
  *
- * Written by Daniel Dinu and Dmitry Khovratovich, 2015
+ * Copyright 2015
+ * Daniel Dinu, Dmitry Khovratovich, Jean-Philippe Aumasson, and Samuel Neves
  *
- * This work is licensed under a Creative Commons CC0 1.0 License/Waiver.
+ * 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:
  *
- * 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/>.
+ * - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0
+ * - Apache 2.0        : http://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.
  */
 
 #include <stdint.h>
@@ -145,7 +149,10 @@ void fill_segment(const argon2_instance_t *instance,
         return;
     }
 
-    data_independent_addressing = (instance->type == Argon2_i);
+    data_independent_addressing =
+        (instance->type == Argon2_i) ||
+        (instance->type == Argon2_id && (position.pass == 0) &&
+         (position.slice < ARGON2_SYNC_POINTS / 2));
 
     pseudo_rands =
         (uint64_t *)malloc(sizeof(uint64_t) * (instance->segment_length));
diff --git a/src/argon2/ref.h b/src/argon2/ref.h
index 8d06b2a8..1820b224 100644
--- a/src/argon2/ref.h
+++ b/src/argon2/ref.h
@@ -1,14 +1,18 @@
 /*
- * Argon2 source code package
+ * Argon2 reference source code package - reference C implementations
  *
- * Written by Daniel Dinu and Dmitry Khovratovich, 2015
+ * Copyright 2015
+ * Daniel Dinu, Dmitry Khovratovich, Jean-Philippe Aumasson, and Samuel Neves
  *
- * This work is licensed under a Creative Commons CC0 1.0 License/Waiver.
+ * 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:
  *
- * 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/>.
+ * - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0
+ * - Apache 2.0        : http://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_REF_H
diff --git a/src/argon2/thread.c b/src/argon2/thread.c
index 412261f1..5de2c133 100644
--- a/src/argon2/thread.c
+++ b/src/argon2/thread.c
@@ -1,3 +1,20 @@
+/*
+ * 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 : http://creativecommons.org/publicdomain/zero/1.0
+ * - Apache 2.0        : http://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.
+ */
+
 #include "thread.h"
 #if defined(_WIN32)
 #include <windows.h>
diff --git a/src/argon2/thread.h b/src/argon2/thread.h
index 57c4ce56..f04bb407 100644
--- a/src/argon2/thread.h
+++ b/src/argon2/thread.h
@@ -1,3 +1,20 @@
+/*
+ * 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 : http://creativecommons.org/publicdomain/zero/1.0
+ * - Apache 2.0        : http://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_THREAD_H
 #define ARGON2_THREAD_H
 /*
-- 
GitLab