/* See LICENSE file for copyright and license details. */ #include "common.h" static size_t encode_params(char *buf, size_t bufsize, const struct libar2_argon2_parameters *params) { if (params->salt) { return libar2_encode_params(buf, params); } return 1 + (size_t)snprintf(buf, bufsize, "$%s$v=%i$m=%lu,t=%lu,p=%lu$*%zu$", libar2_type_to_string(params->type, LIBAR2_LOWER_CASE), (int)params->version, (unsigned long int)params->m_cost, (unsigned long int)params->t_cost, (unsigned long int)params->lanes, params->saltlen); } char * libar2simplified_encode(const struct libar2_argon2_parameters *params_, void *hash) { struct libar2_argon2_parameters params = *params_; size_t size, off; char *ret; if (libar2_validate_params(¶ms, NULL) != LIBAR2_OK) { errno = EINVAL; return NULL; } size = encode_params(NULL, 0, ¶ms); if (hash) size += libar2_encode_base64(NULL, NULL, params.hashlen) - 1; else size += (size_t)snprintf(NULL, 0, "*%zu", params.hashlen); ret = malloc(size); if (!ret) { errno = ENOMEM; return NULL; } off = encode_params(ret, size, ¶ms) - 1; if (off > size - 1) abort(); if (hash) off += libar2_encode_base64(&ret[off], hash, params.hashlen) - 1; else off += (size_t)sprintf(&ret[off], "*%zu", params.hashlen); if (off > size - 1) abort(); return ret; }