"Fossies" - the Fresh Open Source Software Archive

Member "cryptsetup-2.4.3/lib/crypto_backend/argon2/argon2.c" (13 Jan 2022, 14664 Bytes) of package /linux/misc/cryptsetup-2.4.3.tar.xz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "argon2.c" see the Fossies "Dox" file reference documentation and the last Fossies "Diffs" side-by-side code changes report: 2.3.5_vs_2.3.6.

    1 /*
    2  * Argon2 reference source code package - reference C implementations
    3  *
    4  * Copyright 2015
    5  * Daniel Dinu, Dmitry Khovratovich, Jean-Philippe Aumasson, and Samuel Neves
    6  *
    7  * You may use this work under the terms of a Creative Commons CC0 1.0
    8  * License/Waiver or the Apache Public License 2.0, at your option. The terms of
    9  * these licenses can be found at:
   10  *
   11  * - CC0 1.0 Universal : https://creativecommons.org/publicdomain/zero/1.0
   12  * - Apache 2.0        : https://www.apache.org/licenses/LICENSE-2.0
   13  *
   14  * You should have received a copy of both of these licenses along with this
   15  * software. If not, they may be obtained at the above URLs.
   16  */
   17 
   18 #include <string.h>
   19 #include <stdlib.h>
   20 #include <stdio.h>
   21 
   22 #include "argon2.h"
   23 #include "encoding.h"
   24 #include "core.h"
   25 
   26 /* to silent gcc -Wcast-qual for const cast */
   27 #define CONST_CAST(x) (x)(uintptr_t)
   28 
   29 const char *argon2_type2string(argon2_type type, int uppercase) {
   30     switch (type) {
   31         case Argon2_d:
   32             return uppercase ? "Argon2d" : "argon2d";
   33         case Argon2_i:
   34             return uppercase ? "Argon2i" : "argon2i";
   35         case Argon2_id:
   36             return uppercase ? "Argon2id" : "argon2id";
   37     }
   38 
   39     return NULL;
   40 }
   41 
   42 int argon2_ctx(argon2_context *context, argon2_type type) {
   43     /* 1. Validate all inputs */
   44     int result = validate_inputs(context);
   45     uint32_t memory_blocks, segment_length;
   46     argon2_instance_t instance;
   47 
   48     if (ARGON2_OK != result) {
   49         return result;
   50     }
   51 
   52     if (Argon2_d != type && Argon2_i != type && Argon2_id != type) {
   53         return ARGON2_INCORRECT_TYPE;
   54     }
   55 
   56     /* 2. Align memory size */
   57     /* Minimum memory_blocks = 8L blocks, where L is the number of lanes */
   58     memory_blocks = context->m_cost;
   59 
   60     if (memory_blocks < 2 * ARGON2_SYNC_POINTS * context->lanes) {
   61         memory_blocks = 2 * ARGON2_SYNC_POINTS * context->lanes;
   62     }
   63 
   64     segment_length = memory_blocks / (context->lanes * ARGON2_SYNC_POINTS);
   65     /* Ensure that all segments have equal length */
   66     memory_blocks = segment_length * (context->lanes * ARGON2_SYNC_POINTS);
   67 
   68     instance.version = context->version;
   69     instance.memory = NULL;
   70     instance.passes = context->t_cost;
   71     instance.memory_blocks = memory_blocks;
   72     instance.segment_length = segment_length;
   73     instance.lane_length = segment_length * ARGON2_SYNC_POINTS;
   74     instance.lanes = context->lanes;
   75     instance.threads = context->threads;
   76     instance.type = type;
   77 
   78     if (instance.threads > instance.lanes) {
   79         instance.threads = instance.lanes;
   80     }
   81 
   82     /* 3. Initialization: Hashing inputs, allocating memory, filling first
   83      * blocks
   84      */
   85     result = initialize(&instance, context);
   86 
   87     if (ARGON2_OK != result) {
   88         return result;
   89     }
   90 
   91     /* 4. Filling memory */
   92     result = fill_memory_blocks(&instance);
   93 
   94     if (ARGON2_OK != result) {
   95         return result;
   96     }
   97     /* 5. Finalization */
   98     finalize(context, &instance);
   99 
  100     return ARGON2_OK;
  101 }
  102 
  103 int argon2_hash(const uint32_t t_cost, const uint32_t m_cost,
  104                 const uint32_t parallelism, const void *pwd,
  105                 const size_t pwdlen, const void *salt, const size_t saltlen,
  106                 void *hash, const size_t hashlen, char *encoded,
  107                 const size_t encodedlen, argon2_type type,
  108                 const uint32_t version){
  109 
  110     argon2_context context;
  111     int result;
  112     uint8_t *out;
  113 
  114     if (pwdlen > ARGON2_MAX_PWD_LENGTH) {
  115         return ARGON2_PWD_TOO_LONG;
  116     }
  117 
  118     if (saltlen > ARGON2_MAX_SALT_LENGTH) {
  119         return ARGON2_SALT_TOO_LONG;
  120     }
  121 
  122     if (hashlen > ARGON2_MAX_OUTLEN) {
  123         return ARGON2_OUTPUT_TOO_LONG;
  124     }
  125 
  126     if (hashlen < ARGON2_MIN_OUTLEN) {
  127         return ARGON2_OUTPUT_TOO_SHORT;
  128     }
  129 
  130     out = malloc(hashlen);
  131     if (!out) {
  132         return ARGON2_MEMORY_ALLOCATION_ERROR;
  133     }
  134 
  135     context.out = (uint8_t *)out;
  136     context.outlen = (uint32_t)hashlen;
  137     context.pwd = CONST_CAST(uint8_t *)pwd;
  138     context.pwdlen = (uint32_t)pwdlen;
  139     context.salt = CONST_CAST(uint8_t *)salt;
  140     context.saltlen = (uint32_t)saltlen;
  141     context.secret = NULL;
  142     context.secretlen = 0;
  143     context.ad = NULL;
  144     context.adlen = 0;
  145     context.t_cost = t_cost;
  146     context.m_cost = m_cost;
  147     context.lanes = parallelism;
  148     context.threads = parallelism;
  149     context.allocate_cbk = NULL;
  150     context.free_cbk = NULL;
  151     context.flags = ARGON2_DEFAULT_FLAGS;
  152     context.version = version;
  153 
  154     result = argon2_ctx(&context, type);
  155 
  156     if (result != ARGON2_OK) {
  157         clear_internal_memory(out, hashlen);
  158         free(out);
  159         return result;
  160     }
  161 
  162     /* if raw hash requested, write it */
  163     if (hash) {
  164         memcpy(hash, out, hashlen);
  165     }
  166 
  167     /* if encoding requested, write it */
  168     if (encoded && encodedlen) {
  169         if (encode_string(encoded, encodedlen, &context, type) != ARGON2_OK) {
  170             clear_internal_memory(out, hashlen); /* wipe buffers if error */
  171             clear_internal_memory(encoded, encodedlen);
  172             free(out);
  173             return ARGON2_ENCODING_FAIL;
  174         }
  175     }
  176     clear_internal_memory(out, hashlen);
  177     free(out);
  178 
  179     return ARGON2_OK;
  180 }
  181 
  182 int argon2i_hash_encoded(const uint32_t t_cost, const uint32_t m_cost,
  183                          const uint32_t parallelism, const void *pwd,
  184                          const size_t pwdlen, const void *salt,
  185                          const size_t saltlen, const size_t hashlen,
  186                          char *encoded, const size_t encodedlen) {
  187 
  188     return argon2_hash(t_cost, m_cost, parallelism, pwd, pwdlen, salt, saltlen,
  189                        NULL, hashlen, encoded, encodedlen, Argon2_i,
  190                        ARGON2_VERSION_NUMBER);
  191 }
  192 
  193 int argon2i_hash_raw(const uint32_t t_cost, const uint32_t m_cost,
  194                      const uint32_t parallelism, const void *pwd,
  195                      const size_t pwdlen, const void *salt,
  196                      const size_t saltlen, void *hash, const size_t hashlen) {
  197 
  198     return argon2_hash(t_cost, m_cost, parallelism, pwd, pwdlen, salt, saltlen,
  199                        hash, hashlen, NULL, 0, Argon2_i, ARGON2_VERSION_NUMBER);
  200 }
  201 
  202 int argon2d_hash_encoded(const uint32_t t_cost, const uint32_t m_cost,
  203                          const uint32_t parallelism, const void *pwd,
  204                          const size_t pwdlen, const void *salt,
  205                          const size_t saltlen, const size_t hashlen,
  206                          char *encoded, const size_t encodedlen) {
  207 
  208     return argon2_hash(t_cost, m_cost, parallelism, pwd, pwdlen, salt, saltlen,
  209                        NULL, hashlen, encoded, encodedlen, Argon2_d,
  210                        ARGON2_VERSION_NUMBER);
  211 }
  212 
  213 int argon2d_hash_raw(const uint32_t t_cost, const uint32_t m_cost,
  214                      const uint32_t parallelism, const void *pwd,
  215                      const size_t pwdlen, const void *salt,
  216                      const size_t saltlen, void *hash, const size_t hashlen) {
  217 
  218     return argon2_hash(t_cost, m_cost, parallelism, pwd, pwdlen, salt, saltlen,
  219                        hash, hashlen, NULL, 0, Argon2_d, ARGON2_VERSION_NUMBER);
  220 }
  221 
  222 int argon2id_hash_encoded(const uint32_t t_cost, const uint32_t m_cost,
  223                           const uint32_t parallelism, const void *pwd,
  224                           const size_t pwdlen, const void *salt,
  225                           const size_t saltlen, const size_t hashlen,
  226                           char *encoded, const size_t encodedlen) {
  227 
  228     return argon2_hash(t_cost, m_cost, parallelism, pwd, pwdlen, salt, saltlen,
  229                        NULL, hashlen, encoded, encodedlen, Argon2_id,
  230                        ARGON2_VERSION_NUMBER);
  231 }
  232 
  233 int argon2id_hash_raw(const uint32_t t_cost, const uint32_t m_cost,
  234                       const uint32_t parallelism, const void *pwd,
  235                       const size_t pwdlen, const void *salt,
  236                       const size_t saltlen, void *hash, const size_t hashlen) {
  237     return argon2_hash(t_cost, m_cost, parallelism, pwd, pwdlen, salt, saltlen,
  238                        hash, hashlen, NULL, 0, Argon2_id,
  239                        ARGON2_VERSION_NUMBER);
  240 }
  241 
  242 static int argon2_compare(const uint8_t *b1, const uint8_t *b2, size_t len) {
  243     size_t i;
  244     uint8_t d = 0U;
  245 
  246     for (i = 0U; i < len; i++) {
  247         d |= b1[i] ^ b2[i];
  248     }
  249     return (int)((1 & ((d - 1) >> 8)) - 1);
  250 }
  251 
  252 int argon2_verify(const char *encoded, const void *pwd, const size_t pwdlen,
  253                   argon2_type type) {
  254 
  255     argon2_context ctx;
  256     uint8_t *desired_result = NULL;
  257 
  258     int ret = ARGON2_OK;
  259 
  260     size_t encoded_len;
  261     uint32_t max_field_len;
  262 
  263     if (pwdlen > ARGON2_MAX_PWD_LENGTH) {
  264         return ARGON2_PWD_TOO_LONG;
  265     }
  266 
  267     if (encoded == NULL) {
  268         return ARGON2_DECODING_FAIL;
  269     }
  270 
  271     encoded_len = strlen(encoded);
  272     if (encoded_len > UINT32_MAX) {
  273         return ARGON2_DECODING_FAIL;
  274     }
  275 
  276     /* No field can be longer than the encoded length */
  277     /* coverity[strlen_assign] */
  278     max_field_len = (uint32_t)encoded_len;
  279 
  280     ctx.saltlen = max_field_len;
  281     ctx.outlen = max_field_len;
  282 
  283     ctx.salt = malloc(ctx.saltlen);
  284     ctx.out = malloc(ctx.outlen);
  285     if (!ctx.salt || !ctx.out) {
  286         ret = ARGON2_MEMORY_ALLOCATION_ERROR;
  287         goto fail;
  288     }
  289 
  290     ctx.pwd = CONST_CAST(uint8_t *)pwd;
  291     ctx.pwdlen = (uint32_t)pwdlen;
  292 
  293     ret = decode_string(&ctx, encoded, type);
  294     if (ret != ARGON2_OK) {
  295         goto fail;
  296     }
  297 
  298     /* Set aside the desired result, and get a new buffer. */
  299     desired_result = ctx.out;
  300     ctx.out = malloc(ctx.outlen);
  301     if (!ctx.out) {
  302         ret = ARGON2_MEMORY_ALLOCATION_ERROR;
  303         goto fail;
  304     }
  305 
  306     ret = argon2_verify_ctx(&ctx, (char *)desired_result, type);
  307     if (ret != ARGON2_OK) {
  308         goto fail;
  309     }
  310 
  311 fail:
  312     free(ctx.salt);
  313     free(ctx.out);
  314     free(desired_result);
  315 
  316     return ret;
  317 }
  318 
  319 int argon2i_verify(const char *encoded, const void *pwd, const size_t pwdlen) {
  320 
  321     return argon2_verify(encoded, pwd, pwdlen, Argon2_i);
  322 }
  323 
  324 int argon2d_verify(const char *encoded, const void *pwd, const size_t pwdlen) {
  325 
  326     return argon2_verify(encoded, pwd, pwdlen, Argon2_d);
  327 }
  328 
  329 int argon2id_verify(const char *encoded, const void *pwd, const size_t pwdlen) {
  330 
  331     return argon2_verify(encoded, pwd, pwdlen, Argon2_id);
  332 }
  333 
  334 int argon2d_ctx(argon2_context *context) {
  335     return argon2_ctx(context, Argon2_d);
  336 }
  337 
  338 int argon2i_ctx(argon2_context *context) {
  339     return argon2_ctx(context, Argon2_i);
  340 }
  341 
  342 int argon2id_ctx(argon2_context *context) {
  343     return argon2_ctx(context, Argon2_id);
  344 }
  345 
  346 int argon2_verify_ctx(argon2_context *context, const char *hash,
  347                       argon2_type type) {
  348     int ret = argon2_ctx(context, type);
  349     if (ret != ARGON2_OK) {
  350         return ret;
  351     }
  352 
  353     if (argon2_compare(CONST_CAST(uint8_t *)hash, context->out, context->outlen)) {
  354         return ARGON2_VERIFY_MISMATCH;
  355     }
  356 
  357     return ARGON2_OK;
  358 }
  359 
  360 int argon2d_verify_ctx(argon2_context *context, const char *hash) {
  361     return argon2_verify_ctx(context, hash, Argon2_d);
  362 }
  363 
  364 int argon2i_verify_ctx(argon2_context *context, const char *hash) {
  365     return argon2_verify_ctx(context, hash, Argon2_i);
  366 }
  367 
  368 int argon2id_verify_ctx(argon2_context *context, const char *hash) {
  369     return argon2_verify_ctx(context, hash, Argon2_id);
  370 }
  371 
  372 const char *argon2_error_message(int error_code) {
  373     switch (error_code) {
  374     case ARGON2_OK:
  375         return "OK";
  376     case ARGON2_OUTPUT_PTR_NULL:
  377         return "Output pointer is NULL";
  378     case ARGON2_OUTPUT_TOO_SHORT:
  379         return "Output is too short";
  380     case ARGON2_OUTPUT_TOO_LONG:
  381         return "Output is too long";
  382     case ARGON2_PWD_TOO_SHORT:
  383         return "Password is too short";
  384     case ARGON2_PWD_TOO_LONG:
  385         return "Password is too long";
  386     case ARGON2_SALT_TOO_SHORT:
  387         return "Salt is too short";
  388     case ARGON2_SALT_TOO_LONG:
  389         return "Salt is too long";
  390     case ARGON2_AD_TOO_SHORT:
  391         return "Associated data is too short";
  392     case ARGON2_AD_TOO_LONG:
  393         return "Associated data is too long";
  394     case ARGON2_SECRET_TOO_SHORT:
  395         return "Secret is too short";
  396     case ARGON2_SECRET_TOO_LONG:
  397         return "Secret is too long";
  398     case ARGON2_TIME_TOO_SMALL:
  399         return "Time cost is too small";
  400     case ARGON2_TIME_TOO_LARGE:
  401         return "Time cost is too large";
  402     case ARGON2_MEMORY_TOO_LITTLE:
  403         return "Memory cost is too small";
  404     case ARGON2_MEMORY_TOO_MUCH:
  405         return "Memory cost is too large";
  406     case ARGON2_LANES_TOO_FEW:
  407         return "Too few lanes";
  408     case ARGON2_LANES_TOO_MANY:
  409         return "Too many lanes";
  410     case ARGON2_PWD_PTR_MISMATCH:
  411         return "Password pointer is NULL, but password length is not 0";
  412     case ARGON2_SALT_PTR_MISMATCH:
  413         return "Salt pointer is NULL, but salt length is not 0";
  414     case ARGON2_SECRET_PTR_MISMATCH:
  415         return "Secret pointer is NULL, but secret length is not 0";
  416     case ARGON2_AD_PTR_MISMATCH:
  417         return "Associated data pointer is NULL, but ad length is not 0";
  418     case ARGON2_MEMORY_ALLOCATION_ERROR:
  419         return "Memory allocation error";
  420     case ARGON2_FREE_MEMORY_CBK_NULL:
  421         return "The free memory callback is NULL";
  422     case ARGON2_ALLOCATE_MEMORY_CBK_NULL:
  423         return "The allocate memory callback is NULL";
  424     case ARGON2_INCORRECT_PARAMETER:
  425         return "Argon2_Context context is NULL";
  426     case ARGON2_INCORRECT_TYPE:
  427         return "There is no such version of Argon2";
  428     case ARGON2_OUT_PTR_MISMATCH:
  429         return "Output pointer mismatch";
  430     case ARGON2_THREADS_TOO_FEW:
  431         return "Not enough threads";
  432     case ARGON2_THREADS_TOO_MANY:
  433         return "Too many threads";
  434     case ARGON2_MISSING_ARGS:
  435         return "Missing arguments";
  436     case ARGON2_ENCODING_FAIL:
  437         return "Encoding failed";
  438     case ARGON2_DECODING_FAIL:
  439         return "Decoding failed";
  440     case ARGON2_THREAD_FAIL:
  441         return "Threading failure";
  442     case ARGON2_DECODING_LENGTH_FAIL:
  443         return "Some of encoded parameters are too long or too short";
  444     case ARGON2_VERIFY_MISMATCH:
  445         return "The password does not match the supplied hash";
  446     default:
  447         return "Unknown error code";
  448     }
  449 }
  450 
  451 size_t argon2_encodedlen(uint32_t t_cost, uint32_t m_cost, uint32_t parallelism,
  452                          uint32_t saltlen, uint32_t hashlen, argon2_type type) {
  453   if (!argon2_type2string(type, 0))
  454       return 0;
  455   return strlen("$$v=$m=,t=,p=$$") + strlen(argon2_type2string(type, 0)) +
  456          numlen(t_cost) + numlen(m_cost) + numlen(parallelism) +
  457          b64len(saltlen) + b64len(hashlen) + numlen(ARGON2_VERSION_NUMBER) + 1;
  458 }