]> git.proxmox.com Git - ceph.git/blob - ceph/src/crypto/isa-l/isa-l_crypto/mh_sha1/mh_sha1_ref.c
add subtree-ish sources for 12.0.3
[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 #define W(x) w[(x) & 15]
45
46 #define step00_19(i,a,b,c,d,e) \
47 if (i>15) W(i) = rol32(W(i-3)^W(i-8)^W(i-14)^W(i-16), 1); \
48 else W(i) = bswap(ww[i]); \
49 e += rol32(a,5) + F1(b,c,d) + 0x5A827999 + W(i); \
50 b = rol32(b,30)
51
52 #define step20_39(i,a,b,c,d,e) \
53 W(i) = rol32(W(i-3)^W(i-8)^W(i-14)^W(i-16), 1); \
54 e += rol32(a,5) + F2(b,c,d) + 0x6ED9EBA1 + W(i); \
55 b = rol32(b,30)
56
57 #define step40_59(i,a,b,c,d,e) \
58 W(i) = rol32(W(i-3)^W(i-8)^W(i-14)^W(i-16), 1); \
59 e += rol32(a,5) + F3(b,c,d) + 0x8F1BBCDC + W(i); \
60 b = rol32(b,30)
61
62 #define step60_79(i,a,b,c,d,e) \
63 W(i) = rol32(W(i-3)^W(i-8)^W(i-14)^W(i-16), 1); \
64 e += rol32(a,5) + F4(b,c,d) + 0xCA62C1D6 + W(i); \
65 b = rol32(b,30)
66
67 void sha1_single_for_mh_sha1_ref(const uint8_t * data, uint32_t digest[])
68 {
69 uint32_t a, b, c, d, e;
70 uint32_t w[16] = { 0 };
71 uint32_t *ww = (uint32_t *) data;
72
73 a = digest[0];
74 b = digest[1];
75 c = digest[2];
76 d = digest[3];
77 e = digest[4];
78
79 step00_19(0, a, b, c, d, e);
80 step00_19(1, e, a, b, c, d);
81 step00_19(2, d, e, a, b, c);
82 step00_19(3, c, d, e, a, b);
83 step00_19(4, b, c, d, e, a);
84 step00_19(5, a, b, c, d, e);
85 step00_19(6, e, a, b, c, d);
86 step00_19(7, d, e, a, b, c);
87 step00_19(8, c, d, e, a, b);
88 step00_19(9, b, c, d, e, a);
89 step00_19(10, a, b, c, d, e);
90 step00_19(11, e, a, b, c, d);
91 step00_19(12, d, e, a, b, c);
92 step00_19(13, c, d, e, a, b);
93 step00_19(14, b, c, d, e, a);
94 step00_19(15, a, b, c, d, e);
95 step00_19(16, e, a, b, c, d);
96 step00_19(17, d, e, a, b, c);
97 step00_19(18, c, d, e, a, b);
98 step00_19(19, b, c, d, e, a);
99
100 step20_39(20, a, b, c, d, e);
101 step20_39(21, e, a, b, c, d);
102 step20_39(22, d, e, a, b, c);
103 step20_39(23, c, d, e, a, b);
104 step20_39(24, b, c, d, e, a);
105 step20_39(25, a, b, c, d, e);
106 step20_39(26, e, a, b, c, d);
107 step20_39(27, d, e, a, b, c);
108 step20_39(28, c, d, e, a, b);
109 step20_39(29, b, c, d, e, a);
110 step20_39(30, a, b, c, d, e);
111 step20_39(31, e, a, b, c, d);
112 step20_39(32, d, e, a, b, c);
113 step20_39(33, c, d, e, a, b);
114 step20_39(34, b, c, d, e, a);
115 step20_39(35, a, b, c, d, e);
116 step20_39(36, e, a, b, c, d);
117 step20_39(37, d, e, a, b, c);
118 step20_39(38, c, d, e, a, b);
119 step20_39(39, b, c, d, e, a);
120
121 step40_59(40, a, b, c, d, e);
122 step40_59(41, e, a, b, c, d);
123 step40_59(42, d, e, a, b, c);
124 step40_59(43, c, d, e, a, b);
125 step40_59(44, b, c, d, e, a);
126 step40_59(45, a, b, c, d, e);
127 step40_59(46, e, a, b, c, d);
128 step40_59(47, d, e, a, b, c);
129 step40_59(48, c, d, e, a, b);
130 step40_59(49, b, c, d, e, a);
131 step40_59(50, a, b, c, d, e);
132 step40_59(51, e, a, b, c, d);
133 step40_59(52, d, e, a, b, c);
134 step40_59(53, c, d, e, a, b);
135 step40_59(54, b, c, d, e, a);
136 step40_59(55, a, b, c, d, e);
137 step40_59(56, e, a, b, c, d);
138 step40_59(57, d, e, a, b, c);
139 step40_59(58, c, d, e, a, b);
140 step40_59(59, b, c, d, e, a);
141
142 step60_79(60, a, b, c, d, e);
143 step60_79(61, e, a, b, c, d);
144 step60_79(62, d, e, a, b, c);
145 step60_79(63, c, d, e, a, b);
146 step60_79(64, b, c, d, e, a);
147 step60_79(65, a, b, c, d, e);
148 step60_79(66, e, a, b, c, d);
149 step60_79(67, d, e, a, b, c);
150 step60_79(68, c, d, e, a, b);
151 step60_79(69, b, c, d, e, a);
152 step60_79(70, a, b, c, d, e);
153 step60_79(71, e, a, b, c, d);
154 step60_79(72, d, e, a, b, c);
155 step60_79(73, c, d, e, a, b);
156 step60_79(74, b, c, d, e, a);
157 step60_79(75, a, b, c, d, e);
158 step60_79(76, e, a, b, c, d);
159 step60_79(77, d, e, a, b, c);
160 step60_79(78, c, d, e, a, b);
161 step60_79(79, b, c, d, e, a);
162
163 digest[0] += a;
164 digest[1] += b;
165 digest[2] += c;
166 digest[3] += d;
167 digest[4] += e;
168 }
169
170 void sha1_for_mh_sha1_ref(const uint8_t * input_data, uint32_t * digest, const uint32_t len)
171 {
172 uint32_t i, j;
173 uint8_t buf[2 * SHA1_BLOCK_SIZE];
174 union {
175 uint64_t uint;
176 uint8_t uchar[8];
177 } convert;
178 uint8_t *p;
179
180 digest[0] = MH_SHA1_H0;
181 digest[1] = MH_SHA1_H1;
182 digest[2] = MH_SHA1_H2;
183 digest[3] = MH_SHA1_H3;
184 digest[4] = MH_SHA1_H4;
185
186 i = len;
187 while (i >= SHA1_BLOCK_SIZE) {
188 sha1_single_for_mh_sha1_ref(input_data, digest);
189 input_data += SHA1_BLOCK_SIZE;
190 i -= SHA1_BLOCK_SIZE;
191 }
192
193 memcpy(buf, input_data, i);
194 buf[i++] = 0x80;
195 for (j = i; j < ((2 * SHA1_BLOCK_SIZE) - 8); j++)
196 buf[j] = 0;
197
198 if (i > SHA1_BLOCK_SIZE - 8)
199 i = 2 * SHA1_BLOCK_SIZE;
200 else
201 i = SHA1_BLOCK_SIZE;
202
203 convert.uint = 8 * len;
204 p = buf + i - 8;
205 p[0] = convert.uchar[7];
206 p[1] = convert.uchar[6];
207 p[2] = convert.uchar[5];
208 p[3] = convert.uchar[4];
209 p[4] = convert.uchar[3];
210 p[5] = convert.uchar[2];
211 p[6] = convert.uchar[1];
212 p[7] = convert.uchar[0];
213
214 sha1_single_for_mh_sha1_ref(buf, digest);
215 if (i == (2 * SHA1_BLOCK_SIZE))
216 sha1_single_for_mh_sha1_ref(buf + SHA1_BLOCK_SIZE, digest);
217 }
218
219 /*
220 * buffer to rearrange one segment data from one block.
221 *
222 * Layout of new_data:
223 * segment
224 * -------------------------
225 * w0 | w1 | ... | w15
226 *
227 */
228 static inline void transform_input_single(uint32_t * new_data, uint32_t * input,
229 uint32_t segment)
230 {
231 new_data[16 * segment + 0] = input[16 * 0 + segment];
232 new_data[16 * segment + 1] = input[16 * 1 + segment];
233 new_data[16 * segment + 2] = input[16 * 2 + segment];
234 new_data[16 * segment + 3] = input[16 * 3 + segment];
235 new_data[16 * segment + 4] = input[16 * 4 + segment];
236 new_data[16 * segment + 5] = input[16 * 5 + segment];
237 new_data[16 * segment + 6] = input[16 * 6 + segment];
238 new_data[16 * segment + 7] = input[16 * 7 + segment];
239 new_data[16 * segment + 8] = input[16 * 8 + segment];
240 new_data[16 * segment + 9] = input[16 * 9 + segment];
241 new_data[16 * segment + 10] = input[16 * 10 + segment];
242 new_data[16 * segment + 11] = input[16 * 11 + segment];
243 new_data[16 * segment + 12] = input[16 * 12 + segment];
244 new_data[16 * segment + 13] = input[16 * 13 + segment];
245 new_data[16 * segment + 14] = input[16 * 14 + segment];
246 new_data[16 * segment + 15] = input[16 * 15 + segment];
247 }
248
249 // Adapt parameters to sha1_single_for_mh_sha1_ref
250 #define sha1_update_one_seg(data, digest) \
251 sha1_single_for_mh_sha1_ref((const uint8_t *)(data), (uint32_t *)(digest))
252
253 /*
254 * buffer to Rearrange all segments data from one block.
255 *
256 * Layout of new_data:
257 * segment
258 * -------------------------
259 * seg0: | w0 | w1 | ... | w15
260 * seg1: | w0 | w1 | ... | w15
261 * seg2: | w0 | w1 | ... | w15
262 * ....
263 * seg15: | w0 | w1 | ... | w15
264 *
265 */
266 static inline void transform_input(uint32_t * new_data, uint32_t * input, uint32_t block)
267 {
268 uint32_t *current_input = input + block * MH_SHA1_BLOCK_SIZE / 4;
269
270 transform_input_single(new_data, current_input, 0);
271 transform_input_single(new_data, current_input, 1);
272 transform_input_single(new_data, current_input, 2);
273 transform_input_single(new_data, current_input, 3);
274 transform_input_single(new_data, current_input, 4);
275 transform_input_single(new_data, current_input, 5);
276 transform_input_single(new_data, current_input, 6);
277 transform_input_single(new_data, current_input, 7);
278 transform_input_single(new_data, current_input, 8);
279 transform_input_single(new_data, current_input, 9);
280 transform_input_single(new_data, current_input, 10);
281 transform_input_single(new_data, current_input, 11);
282 transform_input_single(new_data, current_input, 12);
283 transform_input_single(new_data, current_input, 13);
284 transform_input_single(new_data, current_input, 14);
285 transform_input_single(new_data, current_input, 15);
286
287 }
288
289 /*
290 * buffer to Calculate all segments' digests from one block.
291 *
292 * Layout of seg_digest:
293 * segment
294 * -------------------------
295 * seg0: | H0 | H1 | ... | H4
296 * seg1: | H0 | H1 | ... | H4
297 * seg2: | H0 | H1 | ... | H4
298 * ....
299 * seg15: | H0 | H1 | ... | H4
300 *
301 */
302 static inline void sha1_update_all_segs(uint32_t * new_data,
303 uint32_t(*mh_sha1_seg_digests)[SHA1_DIGEST_WORDS])
304 {
305 sha1_update_one_seg(&(new_data)[16 * 0], mh_sha1_seg_digests[0]);
306 sha1_update_one_seg(&(new_data)[16 * 1], mh_sha1_seg_digests[1]);
307 sha1_update_one_seg(&(new_data)[16 * 2], mh_sha1_seg_digests[2]);
308 sha1_update_one_seg(&(new_data)[16 * 3], mh_sha1_seg_digests[3]);
309 sha1_update_one_seg(&(new_data)[16 * 4], mh_sha1_seg_digests[4]);
310 sha1_update_one_seg(&(new_data)[16 * 5], mh_sha1_seg_digests[5]);
311 sha1_update_one_seg(&(new_data)[16 * 6], mh_sha1_seg_digests[6]);
312 sha1_update_one_seg(&(new_data)[16 * 7], mh_sha1_seg_digests[7]);
313 sha1_update_one_seg(&(new_data)[16 * 8], mh_sha1_seg_digests[8]);
314 sha1_update_one_seg(&(new_data)[16 * 9], mh_sha1_seg_digests[9]);
315 sha1_update_one_seg(&(new_data)[16 * 10], mh_sha1_seg_digests[10]);
316 sha1_update_one_seg(&(new_data)[16 * 11], mh_sha1_seg_digests[11]);
317 sha1_update_one_seg(&(new_data)[16 * 12], mh_sha1_seg_digests[12]);
318 sha1_update_one_seg(&(new_data)[16 * 13], mh_sha1_seg_digests[13]);
319 sha1_update_one_seg(&(new_data)[16 * 14], mh_sha1_seg_digests[14]);
320 sha1_update_one_seg(&(new_data)[16 * 15], mh_sha1_seg_digests[15]);
321 }
322
323 void mh_sha1_block_ref(const uint8_t * input_data, uint32_t(*digests)[HASH_SEGS],
324 uint8_t frame_buffer[MH_SHA1_BLOCK_SIZE], uint32_t num_blocks)
325 {
326 uint32_t i, j;
327 uint32_t *temp_buffer = (uint32_t *) frame_buffer;
328 uint32_t(*trans_digests)[SHA1_DIGEST_WORDS];
329
330 trans_digests = (uint32_t(*)[SHA1_DIGEST_WORDS]) digests;
331
332 // Re-structure seg_digests from 5*16 to 16*5
333 for (j = 0; j < HASH_SEGS; j++) {
334 for (i = 0; i < SHA1_DIGEST_WORDS; i++) {
335 temp_buffer[j * SHA1_DIGEST_WORDS + i] = digests[i][j];
336 }
337 }
338 memcpy(trans_digests, temp_buffer, 4 * SHA1_DIGEST_WORDS * HASH_SEGS);
339
340 // Calculate digests for all segments, leveraging sha1 API
341 for (i = 0; i < num_blocks; i++) {
342 transform_input(temp_buffer, (uint32_t *) input_data, i);
343 sha1_update_all_segs(temp_buffer, trans_digests);
344 }
345
346 // Re-structure seg_digests from 16*5 to 5*16
347 for (j = 0; j < HASH_SEGS; j++) {
348 for (i = 0; i < SHA1_DIGEST_WORDS; i++) {
349 temp_buffer[i * HASH_SEGS + j] = trans_digests[j][i];
350 }
351 }
352 memcpy(digests, temp_buffer, 4 * SHA1_DIGEST_WORDS * HASH_SEGS);
353
354 return;
355 }
356
357 void mh_sha1_tail_ref(uint8_t * partial_buffer, uint32_t total_len,
358 uint32_t(*mh_sha1_segs_digests)[HASH_SEGS], uint8_t * frame_buffer,
359 uint32_t digests[SHA1_DIGEST_WORDS])
360 {
361 uint64_t partial_buffer_len, len_in_bit;
362
363 partial_buffer_len = total_len % MH_SHA1_BLOCK_SIZE;
364
365 // Padding the first block
366 partial_buffer[partial_buffer_len] = 0x80;
367 partial_buffer_len++;
368 memset(partial_buffer + partial_buffer_len, 0,
369 MH_SHA1_BLOCK_SIZE - partial_buffer_len);
370
371 // Calculate the first block without total_length if padding needs 2 block
372 if (partial_buffer_len > (MH_SHA1_BLOCK_SIZE - 8)) {
373 mh_sha1_block_ref(partial_buffer, mh_sha1_segs_digests, frame_buffer, 1);
374 //Padding the second block
375 memset(partial_buffer, 0, MH_SHA1_BLOCK_SIZE);
376 }
377 //Padding the block
378 len_in_bit = bswap64((uint64_t) total_len * 8);
379 *(uint64_t *) (partial_buffer + MH_SHA1_BLOCK_SIZE - 8) = len_in_bit;
380 mh_sha1_block_ref(partial_buffer, mh_sha1_segs_digests, frame_buffer, 1);
381
382 //Calculate multi-hash SHA1 digests (segment digests as input message)
383 sha1_for_mh_sha1_ref((uint8_t *) mh_sha1_segs_digests, digests,
384 4 * SHA1_DIGEST_WORDS * HASH_SEGS);
385
386 return;
387 }
388
389 void mh_sha1_ref(const void *buffer, uint32_t len, uint32_t * mh_sha1_digest)
390 {
391 uint64_t total_len;
392 uint64_t num_blocks;
393 uint32_t mh_sha1_segs_digests[SHA1_DIGEST_WORDS][HASH_SEGS];
394 uint8_t frame_buffer[MH_SHA1_BLOCK_SIZE];
395 uint8_t partial_block_buffer[MH_SHA1_BLOCK_SIZE * 2];
396 uint32_t mh_sha1_hash_dword[SHA1_DIGEST_WORDS];
397 uint32_t i;
398 const uint8_t *input_data = (const uint8_t *)buffer;
399
400 /* Initialize digests of all segments */
401 for (i = 0; i < HASH_SEGS; i++) {
402 mh_sha1_segs_digests[0][i] = MH_SHA1_H0;
403 mh_sha1_segs_digests[1][i] = MH_SHA1_H1;
404 mh_sha1_segs_digests[2][i] = MH_SHA1_H2;
405 mh_sha1_segs_digests[3][i] = MH_SHA1_H3;
406 mh_sha1_segs_digests[4][i] = MH_SHA1_H4;
407 }
408
409 total_len = len;
410
411 // Calculate blocks
412 num_blocks = len / MH_SHA1_BLOCK_SIZE;
413 if (num_blocks > 0) {
414 //do num_blocks process
415 mh_sha1_block_ref(input_data, mh_sha1_segs_digests, frame_buffer, num_blocks);
416 len -= num_blocks * MH_SHA1_BLOCK_SIZE;
417 input_data += num_blocks * MH_SHA1_BLOCK_SIZE;
418 }
419 // Store the partial block
420 if (len != 0) {
421 memcpy(partial_block_buffer, input_data, len);
422 }
423
424 /* Finalize */
425 mh_sha1_tail_ref(partial_block_buffer, total_len, mh_sha1_segs_digests,
426 frame_buffer, mh_sha1_hash_dword);
427
428 // Output the digests of mh_sha1
429 if (mh_sha1_digest != NULL) {
430 mh_sha1_digest[0] = mh_sha1_hash_dword[0];
431 mh_sha1_digest[1] = mh_sha1_hash_dword[1];
432 mh_sha1_digest[2] = mh_sha1_hash_dword[2];
433 mh_sha1_digest[3] = mh_sha1_hash_dword[3];
434 mh_sha1_digest[4] = mh_sha1_hash_dword[4];
435 }
436
437 return;
438 }