"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 }