diff options
-rw-r--r-- | libar2.h | 5 | ||||
-rw-r--r-- | libar2_decode_params.c | 2 | ||||
-rw-r--r-- | libar2_encode_params.3 | 13 | ||||
-rw-r--r-- | libar2_encode_params.c | 24 | ||||
-rw-r--r-- | libar2_hash.3 | 1 | ||||
-rw-r--r-- | libar2_hash.c | 2 | ||||
-rw-r--r-- | test.c | 48 |
7 files changed, 84 insertions, 11 deletions
@@ -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) { @@ -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(¶ms, 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, ¶ms), sizeof(PARAMSTR)); + assert_zueq(libar2_encode_params(pbuf, ¶ms), 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(¶ms, 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, ¶ms), sizeof(PARAMSTR)); + assert_zueq(libar2_encode_params(pbuf, ¶ms), sizeof(PARAMSTR)); + assert_streq(pbuf, PARAMSTR); + assert(sbuf != NULL); + ctx_st.deallocate(sbuf, &ctx_st); + sbuf = NULL; +#undef PARAMSTR + #undef DECODE } |