Argon2i: fix encoding issues

For compatibility with hashes might have been encoded using other libraries.
This commit is contained in:
Frank Denis
2016-10-26 22:50:38 +02:00
parent aff4aaeabf
commit 71f0693ee7
2 changed files with 32 additions and 56 deletions
@@ -315,37 +315,37 @@ int validate_inputs(const argon2_context *context) {
return ARGON2_OUTPUT_TOO_LONG;
}
/* Validate password length */
/* Validate password (required param) */
if (NULL == context->pwd) {
if (0 != context->pwdlen) {
return ARGON2_PWD_PTR_MISMATCH;
}
} else {
if (ARGON2_MIN_PWD_LENGTH > context->pwdlen) {
return ARGON2_PWD_TOO_SHORT;
}
if (ARGON2_MAX_PWD_LENGTH < context->pwdlen) {
return ARGON2_PWD_TOO_LONG;
}
}
/* Validate salt length */
if (ARGON2_MIN_PWD_LENGTH > context->pwdlen) {
return ARGON2_PWD_TOO_SHORT;
}
if (ARGON2_MAX_PWD_LENGTH < context->pwdlen) {
return ARGON2_PWD_TOO_LONG;
}
/* Validate salt (required param) */
if (NULL == context->salt) {
if (0 != context->saltlen) {
return ARGON2_SALT_PTR_MISMATCH;
}
} else {
if (ARGON2_MIN_SALT_LENGTH > context->saltlen) {
return ARGON2_SALT_TOO_SHORT;
}
if (ARGON2_MAX_SALT_LENGTH < context->saltlen) {
return ARGON2_SALT_TOO_LONG;
}
}
/* Validate secret length */
if (ARGON2_MIN_SALT_LENGTH > context->saltlen) {
return ARGON2_SALT_TOO_SHORT;
}
if (ARGON2_MAX_SALT_LENGTH < context->saltlen) {
return ARGON2_SALT_TOO_LONG;
}
/* Validate secret (optional param) */
if (NULL == context->secret) {
if (0 != context->secretlen) {
return ARGON2_SECRET_PTR_MISMATCH;
@@ -360,7 +360,7 @@ int validate_inputs(const argon2_context *context) {
}
}
/* Validate associated data */
/* Validate associated data (optional param) */
if (NULL == context->ad) {
if (0 != context->adlen) {
return ARGON2_AD_PTR_MISMATCH;
@@ -22,11 +22,6 @@
* the parameters, salts and outputs. It does not compute the hash
* itself.
*
* -- The third section is test code, with a main() function. With
* this section, the whole file compiles as a stand-alone program
* that exercises the encoding and decoding functions with some
* test vectors.
*
* The code was originally written by Thomas Pornin <pornin@bolet.org>,
* to whom comments and remarks may be sent. It is released under what
* should amount to Public Domain or its closest equivalent; the
@@ -229,18 +224,18 @@ static const char *decode_decimal(const char *str, unsigned long *v) {
*
* The code below applies the following format:
*
* $argon2<T>$v=<num>$m=<num>,t=<num>,p=<num>[,keyid=<bin>][,data=<bin>][$<bin>[$<bin>]]
* $argon2<T>[$v=<num>]$m=<num>,t=<num>,p=<num>$<bin>$<bin>
*
* 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.
* where <T> is either '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 last two binary chunks (encoded in Base64) are, in that order,
* the salt and the output. Both are optional, but you cannot have an
* output without a salt. The binary salt length is between 8 and 48 bytes.
* The output length is always exactly 32 bytes.
* the salt and the output. Both are required. The binary salt length and the
* output length must be in the allowed ranges defined in argon2.h.
*
* The ctx struct must contain buffers large enough to hold the salt and pwd
* when it is fed into decode_string.
*/
/*
@@ -258,7 +253,7 @@ int decode_string(argon2_context *ctx, const char *str, argon2_type type) {
str += cc_len; \
} while ((void)0, 0)
/* Prefix checking with supplied code */
/* Optional prefix checking with supplied code */
#define CC_opt(prefix, code) \
do { \
size_t cc_len = strlen(prefix); \
@@ -279,7 +274,7 @@ int decode_string(argon2_context *ctx, const char *str, argon2_type type) {
(x) = dec_x; \
} while ((void)0, 0)
/* Decoding prefix into binary */
/* Decoding base64 into a binary buffer */
#define BIN(buf, max_len, len) \
do { \
size_t bin_len = (max_len); \
@@ -290,16 +285,15 @@ int decode_string(argon2_context *ctx, const char *str, argon2_type type) {
(len) = (uint32_t)bin_len; \
} while ((void)0, 0)
size_t maxadlen = ctx->adlen;
size_t maxsaltlen = ctx->saltlen;
size_t maxoutlen = ctx->outlen;
unsigned long val;
unsigned long version = 0;
int validation_result;
ctx->adlen = 0;
ctx->saltlen = 0;
ctx->outlen = 0;
if (type == Argon2_i) {
CC("$argon2i");
} else {
@@ -330,15 +324,8 @@ int decode_string(argon2_context *ctx, const char *str, argon2_type type) {
ctx->lanes = (uint32_t) val;
ctx->threads = ctx->lanes;
CC_opt(",data=", BIN(ctx->ad, maxadlen, ctx->adlen));
if (*str == 0) {
return ARGON2_OK;
}
CC("$");
BIN(ctx->salt, maxsaltlen, ctx->saltlen);
if (*str == 0) {
return ARGON2_OK;
}
CC("$");
BIN(ctx->out, maxoutlen, ctx->outlen);
validation_result = validate_inputs(ctx);
@@ -432,20 +419,9 @@ int encode_string(char *dst, size_t dst_len, argon2_context *ctx,
SS(",p=");
SX(ctx->lanes);
if (ctx->adlen > 0) {
SS(",data=");
SB(ctx->ad, ctx->adlen);
}
if (ctx->saltlen == 0) {
return ARGON2_OK;
}
SS("$");
SB(ctx->salt, ctx->saltlen);
if (ctx->outlen == 0) {
return ARGON2_OK;
}
SS("$");
SB(ctx->out, ctx->outlen);
return ARGON2_OK;