]> git.proxmox.com Git - ceph.git/blob - ceph/src/crypto/isa-l/isa-l_crypto/mh_sha1/mh_sha1_ref.c
update ceph source to reef 18.1.2
[ceph.git] / ceph / src / crypto / isa-l / isa-l_crypto / mh_sha1 / mh_sha1_ref.c
1 /**********************************************************************
2 Copyright(c) 2011-2016 Intel Corporation All rights reserved.
3
4 Redistribution and use in source and binary forms, with or without
5 modification, are permitted provided that the following conditions
6 are met:
7 * Redistributions of source code must retain the above copyright
8 notice, this list of conditions and the following disclaimer.
9 * Redistributions in binary form must reproduce the above copyright
10 notice, this list of conditions and the following disclaimer in
11 the documentation and/or other materials provided with the
12 distribution.
13 * Neither the name of Intel Corporation nor the names of its
14 contributors may be used to endorse or promote products derived
15 from this software without specific prior written permission.
16
17 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21 OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 **********************************************************************/
29
30 #include <string.h>
31 #include "mh_sha1_internal.h"
32
33 ////////////////////////////////////////////////////////////////////////
34 ////////////////////////////////////////////////////////////////////////
35 // Macros and sub-functions which already exist in source code file
36 // (sha1_for_mh_sha1.c) is part of ISA-L library as internal functions.
37 // The reason why writing them twice is the linking issue caused by
38 // mh_sha1_ref(). mh_sha1_ref() needs these macros and sub-functions
39 // without linking ISA-L library. So mh_sha1_ref() includes them in
40 // order to contain essential sub-functions in its own object file.
41 ////////////////////////////////////////////////////////////////////////
42 ////////////////////////////////////////////////////////////////////////
43
44 #if (__GNUC__ >= 11)
45 # define OPT_FIX __attribute__ ((noipa))
46 #else
47 # define OPT_FIX
48 #endif
49
50 #define W(x) w[(x) & 15]
51
52 #define step00_19(i,a,b,c,d,e) \
53 if (i>15) W(i) = rol32(W(i-3)^W(i-8)^W(i-14)^W(i-16), 1); \
54 else W(i) = to_be32(ww[i]); \
55 e += rol32(a,5) + F1(b,c,d) + 0x5A827999 + W(i); \
56 b = rol32(b,30)
57
58 #define step20_39(i,a,b,c,d,e) \
59 W(i) = rol32(W(i-3)^W(i-8)^W(i-14)^W(i-16), 1); \
60 e += rol32(a,5) + F2(b,c,d) + 0x6ED9EBA1 + W(i); \
61 b = rol32(b,30)
62
63 #define step40_59(i,a,b,c,d,e) \
64 W(i) = rol32(W(i-3)^W(i-8)^W(i-14)^W(i-16), 1); \
65 e += rol32(a,5) + F3(b,c,d) + 0x8F1BBCDC + W(i); \
66 b = rol32(b,30)
67
68 #define step60_79(i,a,b,c,d,e) \
69 W(i) = rol32(W(i-3)^W(i-8)^W(i-14)^W(i-16), 1); \
70 e += rol32(a,5) + F4(b,c,d) + 0xCA62C1D6 + W(i); \
71 b = rol32(b,30)
72
73 static void OPT_FIX sha1_single_for_mh_sha1_ref(const uint8_t * data, uint32_t digest[])
74 {
75 uint32_t a, b, c, d, e;
76 uint32_t w[16] = { 0 };
77 uint32_t *ww = (uint32_t *) data;
78
79 a = digest[0];
80 b = digest[1];
81 c = digest[2];
82 d = digest[3];
83 e = digest[4];
84
85 step00_19(0, a, b, c, d, e);
86 step00_19(1, e, a, b, c, d);
87 step00_19(2, d, e, a, b, c);
88 step00_19(3, c, d, e, a, b);
89 step00_19(4, b, c, d, e, a);
90 step00_19(5, a, b, c, d, e);
91 step00_19(6, e, a, b, c, d);
92 step00_19(7, d, e, a, b, c);
93 step00_19(8, c, d, e, a, b);
94 step00_19(9, b, c, d, e, a);
95 step00_19(10, a, b, c, d, e);
96 step00_19(11, e, a, b, c, d);
97 step00_19(12, d, e, a, b, c);
98 step00_19(13, c, d, e, a, b);
99 step00_19(14, b, c, d, e, a);
100 step00_19(15, a, b, c, d, e);
101 step00_19(16, e, a, b, c, d);
102 step00_19(17, d, e, a, b, c);
103 step00_19(18, c, d, e, a, b);
104 step00_19(19, b, c, d, e, a);
105
106 step20_39(20, a, b, c, d, e);
107 step20_39(21, e, a, b, c, d);
108 step20_39(22, d, e, a, b, c);
109 step20_39(23, c, d, e, a, b);
110 step20_39(24, b, c, d, e, a);
111 step20_39(25, a, b, c, d, e);
112 step20_39(26, e, a, b, c, d);
113 step20_39(27, d, e, a, b, c);
114 step20_39(28, c, d, e, a, b);
115 step20_39(29, b, c, d, e, a);
116 step20_39(30, a, b, c, d, e);
117 step20_39(31, e, a, b, c, d);
118 step20_39(32, d, e, a, b, c);
119 step20_39(33, c, d, e, a, b);
120 step20_39(34, b, c, d, e, a);
121 step20_39(35, a, b, c, d, e);
122 step20_39(36, e, a, b, c, d);
123 step20_39(37, d, e, a, b, c);
124 step20_39(38, c, d, e, a, b);
125 step20_39(39, b, c, d, e, a);
126
127 step40_59(40, a, b, c, d, e);
128 step40_59(41, e, a, b, c, d);
129 step40_59(42, d, e, a, b, c);
130 step40_59(43, c, d, e, a, b);
131 step40_59(44, b, c, d, e, a);
132 step40_59(45, a, b, c, d, e);
133 step40_59(46, e, a, b, c, d);
134 step40_59(47, d, e, a, b, c);
135 step40_59(48, c, d, e, a, b);
136 step40_59(49, b, c, d, e, a);
137 step40_59(50, a, b, c, d, e);
138 step40_59(51, e, a, b, c, d);
139 step40_59(52, d, e, a, b, c);
140 step40_59(53, c, d, e, a, b);
141 step40_59(54, b, c, d, e, a);
142 step40_59(55, a, b, c, d, e);
143 step40_59(56, e, a, b, c, d);
144 step40_59(57, d, e, a, b, c);
145 step40_59(58, c, d, e, a, b);
146 step40_59(59, b, c, d, e, a);
147
148 step60_79(60, a, b, c, d, e);
149 step60_79(61, e, a, b, c, d);
150 step60_79(62, d, e, a, b, c);
151 step60_79(63, c, d, e, a, b);
152 step60_79(64, b, c, d, e, a);
153 step60_79(65, a, b, c, d, e);
154 step60_79(66, e, a, b, c, d);
155 step60_79(67, d, e, a, b, c);
156 step60_79(68, c, d, e, a, b);
157 step60_79(69, b, c, d, e, a);
158 step60_79(70, a, b, c, d, e);
159 step60_79(71, e, a, b, c, d);
160 step60_79(72, d, e, a, b, c);
161 step60_79(73, c, d, e, a, b);
162 step60_79(74, b, c, d, e, a);
163 step60_79(75, a, b, c, d, e);
164 step60_79(76, e, a, b, c, d);
165 step60_79(77, d, e, a, b, c);
166 step60_79(78, c, d, e, a, b);
167 step60_79(79, b, c, d, e, a);
168
169 digest[0] += a;
170 digest[1] += b;
171 digest[2] += c;
172 digest[3] += d;
173 digest[4] += e;
174 }
175
176 void sha1_for_mh_sha1_ref(const uint8_t * input_data, uint32_t * digest, const uint32_t len)
177 {
178 uint32_t i, j;
179 uint8_t buf[2 * SHA1_BLOCK_SIZE];
180
181 digest[0] = MH_SHA1_H0;
182 digest[1] = MH_SHA1_H1;
183 digest[2] = MH_SHA1_H2;
184 digest[3] = MH_SHA1_H3;
185 digest[4] = MH_SHA1_H4;
186
187 i = len;
188 while (i >= SHA1_BLOCK_SIZE) {
189 sha1_single_for_mh_sha1_ref(input_data, digest);
190 input_data += SHA1_BLOCK_SIZE;
191 i -= SHA1_BLOCK_SIZE;
192 }
193
194 memcpy(buf, input_data, i);
195 buf[i++] = 0x80;
196 for (j = i; j < ((2 * SHA1_BLOCK_SIZE) - 8); j++)
197 buf[j] = 0;
198
199 if (i > SHA1_BLOCK_SIZE - 8)
200 i = 2 * SHA1_BLOCK_SIZE;
201 else
202 i = SHA1_BLOCK_SIZE;
203
204 *(uint64_t *) (buf + i - 8) = to_be64((uint64_t) len * 8);
205
206 sha1_single_for_mh_sha1_ref(buf, digest);
207 if (i == (2 * SHA1_BLOCK_SIZE))
208 sha1_single_for_mh_sha1_ref(buf + SHA1_BLOCK_SIZE, digest);
209 }
210
211 /*
212 * buffer to rearrange one segment data from one block.
213 *
214 * Layout of new_data:
215 * segment
216 * -------------------------
217 * w0 | w1 | ... | w15
218 *
219 */
220 static inline void transform_input_single(uint32_t * new_data, uint32_t * input,
221 uint32_t segment)
222 {
223 new_data[16 * segment + 0] = input[16 * 0 + segment];
224 new_data[16 * segment + 1] = input[16 * 1 + segment];
225 new_data[16 * segment + 2] = input[16 * 2 + segment];
226 new_data[16 * segment + 3] = input[16 * 3 + segment];
227 new_data[16 * segment + 4] = input[16 * 4 + segment];
228 new_data[16 * segment + 5] = input[16 * 5 + segment];
229 new_data[16 * segment + 6] = input[16 * 6 + segment];
230 new_data[16 * segment + 7] = input[16 * 7 + segment];
231 new_data[16 * segment + 8] = input[16 * 8 + segment];
232 new_data[16 * segment + 9] = input[16 * 9 + segment];
233 new_data[16 * segment + 10] = input[16 * 10 + segment];
234 new_data[16 * segment + 11] = input[16 * 11 + segment];
235 new_data[16 * segment + 12] = input[16 * 12 + segment];
236 new_data[16 * segment + 13] = input[16 * 13 + segment];
237 new_data[16 * segment + 14] = input[16 * 14 + segment];
238 new_data[16 * segment + 15] = input[16 * 15 + segment];
239 }
240
241 // Adapt parameters to sha1_single_for_mh_sha1_ref
242 #define sha1_update_one_seg(data, digest) \
243 sha1_single_for_mh_sha1_ref((const uint8_t *)(data), (uint32_t *)(digest))
244
245 /*
246 * buffer to Rearrange all segments data from one block.
247 *
248 * Layout of new_data:
249 * segment
250 * -------------------------
251 * seg0: | w0 | w1 | ... | w15
252 * seg1: | w0 | w1 | ... | w15
253 * seg2: | w0 | w1 | ... | w15
254 * ....
255 * seg15: | w0 | w1 | ... | w15
256 *
257 */
258 static inline void transform_input(uint32_t * new_data, uint32_t * input, uint32_t block)
259 {
260 uint32_t *current_input = input + block * MH_SHA1_BLOCK_SIZE / 4;
261
262 transform_input_single(new_data, current_input, 0);
263 transform_input_single(new_data, current_input, 1);
264 transform_input_single(new_data, current_input, 2);
265 transform_input_single(new_data, current_input, 3);
266 transform_input_single(new_data, current_input, 4);
267 transform_input_single(new_data, current_input, 5);
268 transform_input_single(new_data, current_input, 6);
269 transform_input_single(new_data, current_input, 7);
270 transform_input_single(new_data, current_input, 8);
271 transform_input_single(new_data, current_input, 9);
272 transform_input_single(new_data, current_input, 10);
273 transform_input_single(new_data, current_input, 11);
274 transform_input_single(new_data, current_input, 12);
275 transform_input_single(new_data, current_input, 13);
276 transform_input_single(new_data, current_input, 14);
277 transform_input_single(new_data, current_input, 15);
278
279 }
280
281 /*
282 * buffer to Calculate all segments' digests from one block.
283 *
284 * Layout of seg_digest:
285 * segment
286 * -------------------------
287 * seg0: | H0 | H1 | ... | H4
288 * seg1: | H0 | H1 | ... | H4
289 * seg2: | H0 | H1 | ... | H4
290 * ....
291 * seg15: | H0 | H1 | ... | H4
292 *
293 */
294 static inline void sha1_update_all_segs(uint32_t * new_data,
295 uint32_t(*mh_sha1_seg_digests)[SHA1_DIGEST_WORDS])
296 {
297 sha1_update_one_seg(&(new_data)[16 * 0], mh_sha1_seg_digests[0]);
298 sha1_update_one_seg(&(new_data)[16 * 1], mh_sha1_seg_digests[1]);
299 sha1_update_one_seg(&(new_data)[16 * 2], mh_sha1_seg_digests[2]);
300 sha1_update_one_seg(&(new_data)[16 * 3], mh_sha1_seg_digests[3]);
301 sha1_update_one_seg(&(new_data)[16 * 4], mh_sha1_seg_digests[4]);
302 sha1_update_one_seg(&(new_data)[16 * 5], mh_sha1_seg_digests[5]);
303 sha1_update_one_seg(&(new_data)[16 * 6], mh_sha1_seg_digests[6]);
304 sha1_update_one_seg(&(new_data)[16 * 7], mh_sha1_seg_digests[7]);
305 sha1_update_one_seg(&(new_data)[16 * 8], mh_sha1_seg_digests[8]);
306 sha1_update_one_seg(&(new_data)[16 * 9], mh_sha1_seg_digests[9]);
307 sha1_update_one_seg(&(new_data)[16 * 10], mh_sha1_seg_digests[10]);
308 sha1_update_one_seg(&(new_data)[16 * 11], mh_sha1_seg_digests[11]);
309 sha1_update_one_seg(&(new_data)[16 * 12], mh_sha1_seg_digests[12]);
310 sha1_update_one_seg(&(new_data)[16 * 13], mh_sha1_seg_digests[13]);
311 sha1_update_one_seg(&(new_data)[16 * 14], mh_sha1_seg_digests[14]);
312 sha1_update_one_seg(&(new_data)[16 * 15], mh_sha1_seg_digests[15]);
313 }
314
315 void mh_sha1_block_ref(const uint8_t * input_data, uint32_t(*digests)[HASH_SEGS],
316 uint8_t frame_buffer[MH_SHA1_BLOCK_SIZE], uint32_t num_blocks)
317 {
318 uint32_t i, j;
319 uint32_t *temp_buffer = (uint32_t *) frame_buffer;
320 uint32_t(*trans_digests)[SHA1_DIGEST_WORDS];
321
322 trans_digests = (uint32_t(*)[SHA1_DIGEST_WORDS]) digests;
323
324 // Re-structure seg_digests from 5*16 to 16*5
325 for (j = 0; j < HASH_SEGS; j++) {
326 for (i = 0; i < SHA1_DIGEST_WORDS; i++) {
327 temp_buffer[j * SHA1_DIGEST_WORDS + i] = digests[i][j];
328 }
329 }
330 memcpy(trans_digests, temp_buffer, 4 * SHA1_DIGEST_WORDS * HASH_SEGS);
331
332 // Calculate digests for all segments, leveraging sha1 API
333 for (i = 0; i < num_blocks; i++) {
334 transform_input(temp_buffer, (uint32_t *) input_data, i);
335 sha1_update_all_segs(temp_buffer, trans_digests);
336 }
337
338 // Re-structure seg_digests from 16*5 to 5*16
339 for (j = 0; j < HASH_SEGS; j++) {
340 for (i = 0; i < SHA1_DIGEST_WORDS; i++) {
341 temp_buffer[i * HASH_SEGS + j] = trans_digests[j][i];
342 }
343 }
344 memcpy(digests, temp_buffer, 4 * SHA1_DIGEST_WORDS * HASH_SEGS);
345
346 return;
347 }
348
349 void mh_sha1_tail_ref(uint8_t * partial_buffer, uint32_t total_len,
350 uint32_t(*mh_sha1_segs_digests)[HASH_SEGS], uint8_t * frame_buffer,
351 uint32_t digests[SHA1_DIGEST_WORDS])
352 {
353 uint64_t partial_buffer_len, len_in_bit;
354
355 partial_buffer_len = total_len % MH_SHA1_BLOCK_SIZE;
356
357 // Padding the first block
358 partial_buffer[partial_buffer_len] = 0x80;
359 partial_buffer_len++;
360 memset(partial_buffer + partial_buffer_len, 0,
361 MH_SHA1_BLOCK_SIZE - partial_buffer_len);
362
363 // Calculate the first block without total_length if padding needs 2 block
364 if (partial_buffer_len > (MH_SHA1_BLOCK_SIZE - 8)) {
365 mh_sha1_block_ref(partial_buffer, mh_sha1_segs_digests, frame_buffer, 1);
366 //Padding the second block
367 memset(partial_buffer, 0, MH_SHA1_BLOCK_SIZE);
368 }
369 //Padding the block
370 len_in_bit = to_be64((uint64_t) total_len * 8);
371 *(uint64_t *) (partial_buffer + MH_SHA1_BLOCK_SIZE - 8) = len_in_bit;
372 mh_sha1_block_ref(partial_buffer, mh_sha1_segs_digests, frame_buffer, 1);
373
374 //Calculate multi-hash SHA1 digests (segment digests as input message)
375 sha1_for_mh_sha1_ref((uint8_t *) mh_sha1_segs_digests, digests,
376 4 * SHA1_DIGEST_WORDS * HASH_SEGS);
377
378 return;
379 }
380
381 void mh_sha1_ref(const void *buffer, uint32_t len, uint32_t * mh_sha1_digest)
382 {
383 uint64_t total_len;
384 uint64_t num_blocks;
385 uint32_t mh_sha1_segs_digests[SHA1_DIGEST_WORDS][HASH_SEGS];
386 uint8_t frame_buffer[MH_SHA1_BLOCK_SIZE];
387 uint8_t partial_block_buffer[MH_SHA1_BLOCK_SIZE * 2];
388 uint32_t mh_sha1_hash_dword[SHA1_DIGEST_WORDS];
389 uint32_t i;
390 const uint8_t *input_data = (const uint8_t *)buffer;
391
392 /* Initialize digests of all segments */
393 for (i = 0; i < HASH_SEGS; i++) {
394 mh_sha1_segs_digests[0][i] = MH_SHA1_H0;
395 mh_sha1_segs_digests[1][i] = MH_SHA1_H1;
396 mh_sha1_segs_digests[2][i] = MH_SHA1_H2;
397 mh_sha1_segs_digests[3][i] = MH_SHA1_H3;
398 mh_sha1_segs_digests[4][i] = MH_SHA1_H4;
399 }
400
401 total_len = len;
402
403 // Calculate blocks
404 num_blocks = len / MH_SHA1_BLOCK_SIZE;
405 if (num_blocks > 0) {
406 //do num_blocks process
407 mh_sha1_block_ref(input_data, mh_sha1_segs_digests, frame_buffer, num_blocks);
408 len -= num_blocks * MH_SHA1_BLOCK_SIZE;
409 input_data += num_blocks * MH_SHA1_BLOCK_SIZE;
410 }
411 // Store the partial block
412 if (len != 0) {
413 memcpy(partial_block_buffer, input_data, len);
414 }
415
416 /* Finalize */
417 mh_sha1_tail_ref(partial_block_buffer, total_len, mh_sha1_segs_digests,
418 frame_buffer, mh_sha1_hash_dword);
419
420 // Output the digests of mh_sha1
421 if (mh_sha1_digest != NULL) {
422 mh_sha1_digest[0] = mh_sha1_hash_dword[0];
423 mh_sha1_digest[1] = mh_sha1_hash_dword[1];
424 mh_sha1_digest[2] = mh_sha1_hash_dword[2];
425 mh_sha1_digest[3] = mh_sha1_hash_dword[3];
426 mh_sha1_digest[4] = mh_sha1_hash_dword[4];
427 }
428
429 return;
430 }