aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--libar2.h5
-rw-r--r--libar2_decode_params.c2
-rw-r--r--libar2_encode_params.313
-rw-r--r--libar2_encode_params.c24
-rw-r--r--libar2_hash.31
-rw-r--r--libar2_hash.c2
-rw-r--r--test.c48
7 files changed, 84 insertions, 11 deletions
diff --git a/libar2.h b/libar2.h
index 144b430..8915a1a 100644
--- a/libar2.h
+++ b/libar2.h
@@ -55,7 +55,7 @@
#define LIBAR2_MIN_HASHLEN ((size_t)LIBAR2_UINT_LEAST32_C__(4))
#define LIBAR2_MAX_HASHLEN ((size_t)LIBAR2_UINT_LEAST32_C__(0xFFFFffff))
#define LIBAR2_IS_TYPE_OK(T) ((T) == LIBAR2_ARGON2D || (T) == LIBAR2_ARGON2I || (T) == LIBAR2_ARGON2ID || (T) == LIBAR2_ARGON2DS)
-#define LIBAR2_IS_VERSION_OK(V) ((V) == LIBAR2_ARGON2_VERSION_10 || (V) == LIBAR2_ARGON2_VERSION_13)
+#define LIBAR2_IS_VERSION_OK(V) (!(V) || (V) == LIBAR2_ARGON2_VERSION_10 || (V) == LIBAR2_ARGON2_VERSION_13)
/* } */
@@ -180,7 +180,8 @@ struct libar2_argon2_parameters {
enum libar2_argon2_type type;
/**
- * Version number
+ * Version number; or 0 if not specified
+ * (which is equivalent to `LIBAR2_ARGON2_VERSION_10`)
*
* `libar2_latest_argon2_version` is recommended
*/
diff --git a/libar2_decode_params.c b/libar2_decode_params.c
index cc90c24..fa59ab2 100644
--- a/libar2_decode_params.c
+++ b/libar2_decode_params.c
@@ -65,7 +65,7 @@ libar2_decode_params(const char *str, struct libar2_argon2_parameters *params, c
if (*str++ != '$')
goto einval;
} else {
- params->version = LIBAR2_ARGON2_VERSION_10;
+ params->version = 0; /* implicit LIBAR2_ARGON2_VERSION_10 */
}
while (*str && *str != '$') {
diff --git a/libar2_encode_params.3 b/libar2_encode_params.3
index 9f654a4..ad86115 100644
--- a/libar2_encode_params.3
+++ b/libar2_encode_params.3
@@ -72,7 +72,7 @@ with an allocation size of at least the number
of bytes that was returned by the function in
the previous call to it.
.PP
-The created string will have the following format:
+The created string will have the following format
.RS
.B \(dq$%s$v=%i$m=%lu,t=%lu,p=%lu$%s$\(dq,
@@ -84,6 +84,17 @@ The created string will have the following format:
.RI < "base64 encoded salt" >
.RE
+if the version is explicitly specified, and otherwise
+
+.RS
+.B \(dq$%s$m=%lu,t=%lu,p=%lu$%s$\(dq,
+.RI < type >\fB,\fP
+.RI < "memory cost" >\fB,\fP
+.RI < "time cost" >\fB,\fP
+.RI < "parallelism" >\fB,\fP
+.RI < "base64 encoded salt" >
+.RE
+
The string does not encode the \(dqsecret\(dq
(pepper), \(dqassociated data\(dq, or the
\(dqtag\(dq (message hash) length. This string
diff --git a/libar2_encode_params.c b/libar2_encode_params.c
index 498de9c..bcc46b8 100644
--- a/libar2_encode_params.c
+++ b/libar2_encode_params.c
@@ -7,22 +7,34 @@ libar2_encode_params(char *buf, const struct libar2_argon2_parameters *params)
{
size_t off;
-#define FMT_AND_ARGS\
- "$%s$v=%i$m=%lu,t=%lu,p=%lu$",\
- libar2_type_to_string(params->type, LIBAR2_LOWER_CASE),\
- (int)params->version,\
+#define FMT_AND_ARGS_HEAD\
+ "$%s$",\
+ libar2_type_to_string(params->type, LIBAR2_LOWER_CASE)
+
+#define FMT_AND_ARGS_VERSION\
+ "v=%i$",\
+ (int)params->version
+
+#define FMT_AND_ARGS_TAIL\
+ "m=%lu,t=%lu,p=%lu$",\
(unsigned long int)params->m_cost,\
(unsigned long int)params->t_cost,\
(unsigned long int)params->lanes
if (buf) {
- off = (size_t)sprintf(buf, FMT_AND_ARGS);
+ off = (size_t)sprintf(buf, FMT_AND_ARGS_HEAD);
+ if (params->version)
+ off += (size_t)sprintf(&buf[off], FMT_AND_ARGS_VERSION);
+ off += (size_t)sprintf(&buf[off], FMT_AND_ARGS_TAIL);
off += libar2_encode_base64(&buf[off], params->salt, params->saltlen) - 1;
buf[off++] = '$';
buf[off++] = '\0';
} else {
- off = (size_t)snprintf(NULL, 0, FMT_AND_ARGS);
+ off = (size_t)snprintf(NULL, 0, FMT_AND_ARGS_HEAD);
+ if (params->version)
+ off += (size_t)snprintf(NULL, 0, FMT_AND_ARGS_VERSION);
+ off += (size_t)snprintf(NULL, 0, FMT_AND_ARGS_TAIL);
off += libar2_encode_base64(NULL, params->salt, params->saltlen) - 1;
off += 2;
}
diff --git a/libar2_hash.3 b/libar2_hash.3
index da5af43..3240508 100644
--- a/libar2_hash.3
+++ b/libar2_hash.3
@@ -127,6 +127,7 @@ submission to the Password Hashing Competition).
.B params->version
Argon2 version number.
.I LIBAR2_ARGON2_VERSION_10
+or 0 (implicit specification)
for verison 1.0 and
.I LIBAR2_ARGON2_VERSION_13
for version 1.3.
diff --git a/libar2_hash.c b/libar2_hash.c
index 0eb9211..7f3cf3b 100644
--- a/libar2_hash.c
+++ b/libar2_hash.c
@@ -339,7 +339,7 @@ initial_hash(unsigned char hash[static 64], void *msg, size_t msglen,
n += store32(&block[n], (uint_least32_t)params->hashlen);
n += store32(&block[n], params->m_cost);
n += store32(&block[n], params->t_cost);
- n += store32(&block[n], (uint_least32_t)params->version);
+ n += store32(&block[n], (uint_least32_t)(params->version ? params->version : LIBAR2_ARGON2_VERSION_10));
n += store32(&block[n], (uint_least32_t)params->type);
n += store32(&block[n], (uint_least32_t)msglen);
if (msglen) {
diff --git a/test.c b/test.c
index 8172e16..a799b2e 100644
--- a/test.c
+++ b/test.c
@@ -526,6 +526,54 @@ check_libar2_encode_params_libar2_decode_params(void)
sbuf = NULL;
#undef PARAMSTR
+#define PARAMSTR "$argon2i$v=16$m=4096,t=3,p=1$fn5/f35+f38$"
+ memset(&params, 0xFF, sizeof(params));
+ assert_zueq(DECODE(PARAMSTR, "1234"), sizeof(PARAMSTR) - 1);
+ assert(params.type == LIBAR2_ARGON2I);
+ assert(params.version == LIBAR2_ARGON2_VERSION_10);
+ assert(params.t_cost == 3);
+ assert(params.m_cost == 4096);
+ assert(params.lanes == 1);
+ assert(params.salt != NULL);
+ assert(params.saltlen == 8);
+ assert(!memcmp(params.salt, "~~\x7f\x7f~~\x7f\x7f", params.saltlen));
+ assert(!params.key);
+ assert(!params.keylen);
+ assert(!params.ad);
+ assert(!params.adlen);
+ assert(params.hashlen == 3);
+ assert_zueq(libar2_encode_params(NULL, &params), sizeof(PARAMSTR));
+ assert_zueq(libar2_encode_params(pbuf, &params), sizeof(PARAMSTR));
+ assert_streq(pbuf, PARAMSTR);
+ assert(sbuf != NULL);
+ ctx_st.deallocate(sbuf, &ctx_st);
+ sbuf = NULL;
+#undef PARAMSTR
+
+#define PARAMSTR "$argon2i$m=4096,t=3,p=1$fn5/f35+f38$"
+ memset(&params, 0xFF, sizeof(params));
+ assert_zueq(DECODE(PARAMSTR, "1234"), sizeof(PARAMSTR) - 1);
+ assert(params.type == LIBAR2_ARGON2I);
+ assert(params.version == 0);
+ assert(params.t_cost == 3);
+ assert(params.m_cost == 4096);
+ assert(params.lanes == 1);
+ assert(params.salt != NULL);
+ assert(params.saltlen == 8);
+ assert(!memcmp(params.salt, "~~\x7f\x7f~~\x7f\x7f", params.saltlen));
+ assert(!params.key);
+ assert(!params.keylen);
+ assert(!params.ad);
+ assert(!params.adlen);
+ assert(params.hashlen == 3);
+ assert_zueq(libar2_encode_params(NULL, &params), sizeof(PARAMSTR));
+ assert_zueq(libar2_encode_params(pbuf, &params), sizeof(PARAMSTR));
+ assert_streq(pbuf, PARAMSTR);
+ assert(sbuf != NULL);
+ ctx_st.deallocate(sbuf, &ctx_st);
+ sbuf = NULL;
+#undef PARAMSTR
+
#undef DECODE
}