"Fossies" - the Fresh Open Source Software Archive

Member "cryptsetup-2.4.3/lib/crypto_backend/argon2/ref.c" (13 Jan 2022, 7285 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 "ref.c" see the Fossies "Dox" file reference documentation.

    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 <stdint.h>
   19 #include <string.h>
   20 #include <stdlib.h>
   21 
   22 #include "argon2.h"
   23 #include "core.h"
   24 
   25 #include "blake2/blamka-round-ref.h"
   26 #include "blake2/blake2-impl.h"
   27 #include "blake2/blake2.h"
   28 
   29 
   30 /*
   31  * Function fills a new memory block and optionally XORs the old block over the new one.
   32  * @next_block must be initialized.
   33  * @param prev_block Pointer to the previous block
   34  * @param ref_block Pointer to the reference block
   35  * @param next_block Pointer to the block to be constructed
   36  * @param with_xor Whether to XOR into the new block (1) or just overwrite (0)
   37  * @pre all block pointers must be valid
   38  */
   39 static void fill_block(const block *prev_block, const block *ref_block,
   40                        block *next_block, int with_xor) {
   41     block blockR, block_tmp;
   42     unsigned i;
   43 
   44     copy_block(&blockR, ref_block);
   45     xor_block(&blockR, prev_block);
   46     copy_block(&block_tmp, &blockR);
   47     /* Now blockR = ref_block + prev_block and block_tmp = ref_block + prev_block */
   48     if (with_xor) {
   49         /* Saving the next block contents for XOR over: */
   50         xor_block(&block_tmp, next_block);
   51         /* Now blockR = ref_block + prev_block and
   52            block_tmp = ref_block + prev_block + next_block */
   53     }
   54 
   55     /* Apply Blake2 on columns of 64-bit words: (0,1,...,15) , then
   56        (16,17,..31)... finally (112,113,...127) */
   57     for (i = 0; i < 8; ++i) {
   58         BLAKE2_ROUND_NOMSG(
   59             blockR.v[16 * i], blockR.v[16 * i + 1], blockR.v[16 * i + 2],
   60             blockR.v[16 * i + 3], blockR.v[16 * i + 4], blockR.v[16 * i + 5],
   61             blockR.v[16 * i + 6], blockR.v[16 * i + 7], blockR.v[16 * i + 8],
   62             blockR.v[16 * i + 9], blockR.v[16 * i + 10], blockR.v[16 * i + 11],
   63             blockR.v[16 * i + 12], blockR.v[16 * i + 13], blockR.v[16 * i + 14],
   64             blockR.v[16 * i + 15]);
   65     }
   66 
   67     /* Apply Blake2 on rows of 64-bit words: (0,1,16,17,...112,113), then
   68        (2,3,18,19,...,114,115).. finally (14,15,30,31,...,126,127) */
   69     for (i = 0; i < 8; i++) {
   70         BLAKE2_ROUND_NOMSG(
   71             blockR.v[2 * i], blockR.v[2 * i + 1], blockR.v[2 * i + 16],
   72             blockR.v[2 * i + 17], blockR.v[2 * i + 32], blockR.v[2 * i + 33],
   73             blockR.v[2 * i + 48], blockR.v[2 * i + 49], blockR.v[2 * i + 64],
   74             blockR.v[2 * i + 65], blockR.v[2 * i + 80], blockR.v[2 * i + 81],
   75             blockR.v[2 * i + 96], blockR.v[2 * i + 97], blockR.v[2 * i + 112],
   76             blockR.v[2 * i + 113]);
   77     }
   78 
   79     copy_block(next_block, &block_tmp);
   80     xor_block(next_block, &blockR);
   81 }
   82 
   83 static void next_addresses(block *address_block, block *input_block,
   84                            const block *zero_block) {
   85     input_block->v[6]++;
   86     fill_block(zero_block, input_block, address_block, 0);
   87     fill_block(zero_block, address_block, address_block, 0);
   88 }
   89 
   90 void fill_segment(const argon2_instance_t *instance,
   91                   argon2_position_t position) {
   92     block *ref_block = NULL, *curr_block = NULL;
   93     block address_block, input_block, zero_block;
   94     uint64_t pseudo_rand, ref_index, ref_lane;
   95     uint32_t prev_offset, curr_offset;
   96     uint32_t starting_index;
   97     uint32_t i;
   98     int data_independent_addressing;
   99 
  100     if (instance == NULL) {
  101         return;
  102     }
  103 
  104     data_independent_addressing =
  105         (instance->type == Argon2_i) ||
  106         (instance->type == Argon2_id && (position.pass == 0) &&
  107          (position.slice < ARGON2_SYNC_POINTS / 2));
  108 
  109     if (data_independent_addressing) {
  110         init_block_value(&zero_block, 0);
  111         init_block_value(&input_block, 0);
  112 
  113         input_block.v[0] = position.pass;
  114         input_block.v[1] = position.lane;
  115         input_block.v[2] = position.slice;
  116         input_block.v[3] = instance->memory_blocks;
  117         input_block.v[4] = instance->passes;
  118         input_block.v[5] = instance->type;
  119     }
  120 
  121     starting_index = 0;
  122 
  123     if ((0 == position.pass) && (0 == position.slice)) {
  124         starting_index = 2; /* we have already generated the first two blocks */
  125 
  126         /* Don't forget to generate the first block of addresses: */
  127         if (data_independent_addressing) {
  128             next_addresses(&address_block, &input_block, &zero_block);
  129         }
  130     }
  131 
  132     /* Offset of the current block */
  133     curr_offset = position.lane * instance->lane_length +
  134                   position.slice * instance->segment_length + starting_index;
  135 
  136     if (0 == curr_offset % instance->lane_length) {
  137         /* Last block in this lane */
  138         prev_offset = curr_offset + instance->lane_length - 1;
  139     } else {
  140         /* Previous block */
  141         prev_offset = curr_offset - 1;
  142     }
  143 
  144     for (i = starting_index; i < instance->segment_length;
  145          ++i, ++curr_offset, ++prev_offset) {
  146         /*1.1 Rotating prev_offset if needed */
  147         if (curr_offset % instance->lane_length == 1) {
  148             prev_offset = curr_offset - 1;
  149         }
  150 
  151         /* 1.2 Computing the index of the reference block */
  152         /* 1.2.1 Taking pseudo-random value from the previous block */
  153         if (data_independent_addressing) {
  154             if (i % ARGON2_ADDRESSES_IN_BLOCK == 0) {
  155                 next_addresses(&address_block, &input_block, &zero_block);
  156             }
  157             pseudo_rand = address_block.v[i % ARGON2_ADDRESSES_IN_BLOCK];
  158         } else {
  159             pseudo_rand = instance->memory[prev_offset].v[0];
  160         }
  161 
  162         /* 1.2.2 Computing the lane of the reference block */
  163         ref_lane = ((pseudo_rand >> 32)) % instance->lanes;
  164 
  165         if ((position.pass == 0) && (position.slice == 0)) {
  166             /* Can not reference other lanes yet */
  167             ref_lane = position.lane;
  168         }
  169 
  170         /* 1.2.3 Computing the number of possible reference block within the
  171          * lane.
  172          */
  173         position.index = i;
  174         ref_index = index_alpha(instance, &position, pseudo_rand & 0xFFFFFFFF,
  175                                 ref_lane == position.lane);
  176 
  177         /* 2 Creating a new block */
  178         ref_block =
  179             instance->memory + instance->lane_length * ref_lane + ref_index;
  180         curr_block = instance->memory + curr_offset;
  181         if (ARGON2_VERSION_10 == instance->version) {
  182             /* version 1.2.1 and earlier: overwrite, not XOR */
  183             fill_block(instance->memory + prev_offset, ref_block, curr_block, 0);
  184         } else {
  185             if(0 == position.pass) {
  186                 fill_block(instance->memory + prev_offset, ref_block,
  187                            curr_block, 0);
  188             } else {
  189                 fill_block(instance->memory + prev_offset, ref_block,
  190                            curr_block, 1);
  191             }
  192         }
  193     }
  194 }