]> git.proxmox.com Git - ceph.git/blob - ceph/src/crypto/isa-l/isa-l_crypto/mh_sha256/mh_sha256_ref.c
update ceph source to reef 18.1.2
[ceph.git] / ceph / src / crypto / isa-l / isa-l_crypto / mh_sha256 / mh_sha256_ref.c
1 /**********************************************************************
2 Copyright(c) 2011-2017 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_sha256_internal.h"
32
33 ////////////////////////////////////////////////////////////////////////
34 ////////////////////////////////////////////////////////////////////////
35 // Macros and sub-functions which already exist in source code file
36 // (sha256_for_mh_sha256.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_sha256_ref(). mh_sha256_ref() needs these macros and sub-functions
39 // without linking ISA-L library. So mh_sha256_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 step(i,a,b,c,d,e,f,g,h,k) \
47 if (i<16) W(i) = to_be32(ww[i]); \
48 else \
49 W(i) = W(i-16) + S0(W(i-15)) + W(i-7) + S1(W(i-2)); \
50 t2 = s0(a) + maj(a,b,c); \
51 t1 = h + s1(e) + ch(e,f,g) + k + W(i); \
52 d += t1; \
53 h = t1 + t2;
54
55 void sha256_single_for_mh_sha256_ref(const uint8_t * data, uint32_t digest[])
56 {
57 uint32_t a, b, c, d, e, f, g, h, t1, t2;
58 uint32_t w[16];
59 uint32_t *ww = (uint32_t *) data;
60
61 a = digest[0];
62 b = digest[1];
63 c = digest[2];
64 d = digest[3];
65 e = digest[4];
66 f = digest[5];
67 g = digest[6];
68 h = digest[7];
69
70 step(0, a, b, c, d, e, f, g, h, 0x428a2f98);
71 step(1, h, a, b, c, d, e, f, g, 0x71374491);
72 step(2, g, h, a, b, c, d, e, f, 0xb5c0fbcf);
73 step(3, f, g, h, a, b, c, d, e, 0xe9b5dba5);
74 step(4, e, f, g, h, a, b, c, d, 0x3956c25b);
75 step(5, d, e, f, g, h, a, b, c, 0x59f111f1);
76 step(6, c, d, e, f, g, h, a, b, 0x923f82a4);
77 step(7, b, c, d, e, f, g, h, a, 0xab1c5ed5);
78 step(8, a, b, c, d, e, f, g, h, 0xd807aa98);
79 step(9, h, a, b, c, d, e, f, g, 0x12835b01);
80 step(10, g, h, a, b, c, d, e, f, 0x243185be);
81 step(11, f, g, h, a, b, c, d, e, 0x550c7dc3);
82 step(12, e, f, g, h, a, b, c, d, 0x72be5d74);
83 step(13, d, e, f, g, h, a, b, c, 0x80deb1fe);
84 step(14, c, d, e, f, g, h, a, b, 0x9bdc06a7);
85 step(15, b, c, d, e, f, g, h, a, 0xc19bf174);
86 step(16, a, b, c, d, e, f, g, h, 0xe49b69c1);
87 step(17, h, a, b, c, d, e, f, g, 0xefbe4786);
88 step(18, g, h, a, b, c, d, e, f, 0x0fc19dc6);
89 step(19, f, g, h, a, b, c, d, e, 0x240ca1cc);
90 step(20, e, f, g, h, a, b, c, d, 0x2de92c6f);
91 step(21, d, e, f, g, h, a, b, c, 0x4a7484aa);
92 step(22, c, d, e, f, g, h, a, b, 0x5cb0a9dc);
93 step(23, b, c, d, e, f, g, h, a, 0x76f988da);
94 step(24, a, b, c, d, e, f, g, h, 0x983e5152);
95 step(25, h, a, b, c, d, e, f, g, 0xa831c66d);
96 step(26, g, h, a, b, c, d, e, f, 0xb00327c8);
97 step(27, f, g, h, a, b, c, d, e, 0xbf597fc7);
98 step(28, e, f, g, h, a, b, c, d, 0xc6e00bf3);
99 step(29, d, e, f, g, h, a, b, c, 0xd5a79147);
100 step(30, c, d, e, f, g, h, a, b, 0x06ca6351);
101 step(31, b, c, d, e, f, g, h, a, 0x14292967);
102 step(32, a, b, c, d, e, f, g, h, 0x27b70a85);
103 step(33, h, a, b, c, d, e, f, g, 0x2e1b2138);
104 step(34, g, h, a, b, c, d, e, f, 0x4d2c6dfc);
105 step(35, f, g, h, a, b, c, d, e, 0x53380d13);
106 step(36, e, f, g, h, a, b, c, d, 0x650a7354);
107 step(37, d, e, f, g, h, a, b, c, 0x766a0abb);
108 step(38, c, d, e, f, g, h, a, b, 0x81c2c92e);
109 step(39, b, c, d, e, f, g, h, a, 0x92722c85);
110 step(40, a, b, c, d, e, f, g, h, 0xa2bfe8a1);
111 step(41, h, a, b, c, d, e, f, g, 0xa81a664b);
112 step(42, g, h, a, b, c, d, e, f, 0xc24b8b70);
113 step(43, f, g, h, a, b, c, d, e, 0xc76c51a3);
114 step(44, e, f, g, h, a, b, c, d, 0xd192e819);
115 step(45, d, e, f, g, h, a, b, c, 0xd6990624);
116 step(46, c, d, e, f, g, h, a, b, 0xf40e3585);
117 step(47, b, c, d, e, f, g, h, a, 0x106aa070);
118 step(48, a, b, c, d, e, f, g, h, 0x19a4c116);
119 step(49, h, a, b, c, d, e, f, g, 0x1e376c08);
120 step(50, g, h, a, b, c, d, e, f, 0x2748774c);
121 step(51, f, g, h, a, b, c, d, e, 0x34b0bcb5);
122 step(52, e, f, g, h, a, b, c, d, 0x391c0cb3);
123 step(53, d, e, f, g, h, a, b, c, 0x4ed8aa4a);
124 step(54, c, d, e, f, g, h, a, b, 0x5b9cca4f);
125 step(55, b, c, d, e, f, g, h, a, 0x682e6ff3);
126 step(56, a, b, c, d, e, f, g, h, 0x748f82ee);
127 step(57, h, a, b, c, d, e, f, g, 0x78a5636f);
128 step(58, g, h, a, b, c, d, e, f, 0x84c87814);
129 step(59, f, g, h, a, b, c, d, e, 0x8cc70208);
130 step(60, e, f, g, h, a, b, c, d, 0x90befffa);
131 step(61, d, e, f, g, h, a, b, c, 0xa4506ceb);
132 step(62, c, d, e, f, g, h, a, b, 0xbef9a3f7);
133 step(63, b, c, d, e, f, g, h, a, 0xc67178f2);
134
135 digest[0] += a;
136 digest[1] += b;
137 digest[2] += c;
138 digest[3] += d;
139 digest[4] += e;
140 digest[5] += f;
141 digest[6] += g;
142 digest[7] += h;
143 }
144
145 void sha256_for_mh_sha256_ref(const uint8_t * input_data, uint32_t * digest,
146 const uint32_t len)
147 {
148 uint32_t i, j;
149 uint8_t buf[2 * SHA256_BLOCK_SIZE];
150
151 digest[0] = MH_SHA256_H0;
152 digest[1] = MH_SHA256_H1;
153 digest[2] = MH_SHA256_H2;
154 digest[3] = MH_SHA256_H3;
155 digest[4] = MH_SHA256_H4;
156 digest[5] = MH_SHA256_H5;
157 digest[6] = MH_SHA256_H6;
158 digest[7] = MH_SHA256_H7;
159
160 i = len;
161 while (i >= SHA256_BLOCK_SIZE) {
162 sha256_single_for_mh_sha256_ref(input_data, digest);
163 input_data += SHA256_BLOCK_SIZE;
164 i -= SHA256_BLOCK_SIZE;
165 }
166
167 memcpy(buf, input_data, i);
168 buf[i++] = 0x80;
169 for (j = i; j < ((2 * SHA256_BLOCK_SIZE) - 8); j++)
170 buf[j] = 0;
171
172 if (i > SHA256_BLOCK_SIZE - 8)
173 i = 2 * SHA256_BLOCK_SIZE;
174 else
175 i = SHA256_BLOCK_SIZE;
176
177 *(uint64_t *) (buf + i - 8) = to_be64((uint64_t) len * 8);
178
179 sha256_single_for_mh_sha256_ref(buf, digest);
180 if (i == (2 * SHA256_BLOCK_SIZE))
181 sha256_single_for_mh_sha256_ref(buf + SHA256_BLOCK_SIZE, digest);
182 }
183
184 /*
185 * buffer to rearrange one segment data from one block.
186 *
187 * Layout of new_data:
188 * segment
189 * -------------------------
190 * w0 | w1 | ... | w15
191 *
192 */
193 static inline void transform_input_single(uint32_t * new_data, uint32_t * input,
194 uint32_t segment)
195 {
196 new_data[16 * segment + 0] = input[16 * 0 + segment];
197 new_data[16 * segment + 1] = input[16 * 1 + segment];
198 new_data[16 * segment + 2] = input[16 * 2 + segment];
199 new_data[16 * segment + 3] = input[16 * 3 + segment];
200 new_data[16 * segment + 4] = input[16 * 4 + segment];
201 new_data[16 * segment + 5] = input[16 * 5 + segment];
202 new_data[16 * segment + 6] = input[16 * 6 + segment];
203 new_data[16 * segment + 7] = input[16 * 7 + segment];
204 new_data[16 * segment + 8] = input[16 * 8 + segment];
205 new_data[16 * segment + 9] = input[16 * 9 + segment];
206 new_data[16 * segment + 10] = input[16 * 10 + segment];
207 new_data[16 * segment + 11] = input[16 * 11 + segment];
208 new_data[16 * segment + 12] = input[16 * 12 + segment];
209 new_data[16 * segment + 13] = input[16 * 13 + segment];
210 new_data[16 * segment + 14] = input[16 * 14 + segment];
211 new_data[16 * segment + 15] = input[16 * 15 + segment];
212 }
213
214 // Adapt parameters to sha256_single_for_mh_sha256_ref
215 #define sha256_update_one_seg(data, digest) \
216 sha256_single_for_mh_sha256_ref((const uint8_t *)(data), (uint32_t *)(digest))
217
218 /*
219 * buffer to Rearrange all segments data from one block.
220 *
221 * Layout of new_data:
222 * segment
223 * -------------------------
224 * seg0: | w0 | w1 | ... | w15
225 * seg1: | w0 | w1 | ... | w15
226 * seg2: | w0 | w1 | ... | w15
227 * ....
228 * seg15: | w0 | w1 | ... | w15
229 *
230 */
231 static inline void transform_input(uint32_t * new_data, uint32_t * input, uint32_t block)
232 {
233 uint32_t *current_input = input + block * MH_SHA256_BLOCK_SIZE / 4;
234
235 transform_input_single(new_data, current_input, 0);
236 transform_input_single(new_data, current_input, 1);
237 transform_input_single(new_data, current_input, 2);
238 transform_input_single(new_data, current_input, 3);
239 transform_input_single(new_data, current_input, 4);
240 transform_input_single(new_data, current_input, 5);
241 transform_input_single(new_data, current_input, 6);
242 transform_input_single(new_data, current_input, 7);
243 transform_input_single(new_data, current_input, 8);
244 transform_input_single(new_data, current_input, 9);
245 transform_input_single(new_data, current_input, 10);
246 transform_input_single(new_data, current_input, 11);
247 transform_input_single(new_data, current_input, 12);
248 transform_input_single(new_data, current_input, 13);
249 transform_input_single(new_data, current_input, 14);
250 transform_input_single(new_data, current_input, 15);
251
252 }
253
254 /*
255 * buffer to Calculate all segments' digests from one block.
256 *
257 * Layout of seg_digest:
258 * segment
259 * -------------------------
260 * seg0: | H0 | H1 | ... | H7
261 * seg1: | H0 | H1 | ... | H7
262 * seg2: | H0 | H1 | ... | H7
263 * ....
264 * seg15: | H0 | H1 | ... | H7
265 *
266 */
267 static inline void sha256_update_all_segs(uint32_t * new_data, uint32_t(*mh_sha256_seg_digests)
268 [SHA256_DIGEST_WORDS])
269 {
270 sha256_update_one_seg(&(new_data)[16 * 0], mh_sha256_seg_digests[0]);
271 sha256_update_one_seg(&(new_data)[16 * 1], mh_sha256_seg_digests[1]);
272 sha256_update_one_seg(&(new_data)[16 * 2], mh_sha256_seg_digests[2]);
273 sha256_update_one_seg(&(new_data)[16 * 3], mh_sha256_seg_digests[3]);
274 sha256_update_one_seg(&(new_data)[16 * 4], mh_sha256_seg_digests[4]);
275 sha256_update_one_seg(&(new_data)[16 * 5], mh_sha256_seg_digests[5]);
276 sha256_update_one_seg(&(new_data)[16 * 6], mh_sha256_seg_digests[6]);
277 sha256_update_one_seg(&(new_data)[16 * 7], mh_sha256_seg_digests[7]);
278 sha256_update_one_seg(&(new_data)[16 * 8], mh_sha256_seg_digests[8]);
279 sha256_update_one_seg(&(new_data)[16 * 9], mh_sha256_seg_digests[9]);
280 sha256_update_one_seg(&(new_data)[16 * 10], mh_sha256_seg_digests[10]);
281 sha256_update_one_seg(&(new_data)[16 * 11], mh_sha256_seg_digests[11]);
282 sha256_update_one_seg(&(new_data)[16 * 12], mh_sha256_seg_digests[12]);
283 sha256_update_one_seg(&(new_data)[16 * 13], mh_sha256_seg_digests[13]);
284 sha256_update_one_seg(&(new_data)[16 * 14], mh_sha256_seg_digests[14]);
285 sha256_update_one_seg(&(new_data)[16 * 15], mh_sha256_seg_digests[15]);
286 }
287
288 void mh_sha256_block_ref(const uint8_t * input_data, uint32_t(*digests)[HASH_SEGS],
289 uint8_t frame_buffer[MH_SHA256_BLOCK_SIZE], uint32_t num_blocks)
290 {
291 uint32_t i, j;
292 uint32_t *temp_buffer = (uint32_t *) frame_buffer;
293 uint32_t(*trans_digests)[SHA256_DIGEST_WORDS];
294
295 trans_digests = (uint32_t(*)[SHA256_DIGEST_WORDS]) digests;
296
297 // Re-structure seg_digests from 5*16 to 16*5
298 for (j = 0; j < HASH_SEGS; j++) {
299 for (i = 0; i < SHA256_DIGEST_WORDS; i++) {
300 temp_buffer[j * SHA256_DIGEST_WORDS + i] = digests[i][j];
301 }
302 }
303 memcpy(trans_digests, temp_buffer, 4 * SHA256_DIGEST_WORDS * HASH_SEGS);
304
305 // Calculate digests for all segments, leveraging sha256 API
306 for (i = 0; i < num_blocks; i++) {
307 transform_input(temp_buffer, (uint32_t *) input_data, i);
308 sha256_update_all_segs(temp_buffer, trans_digests);
309 }
310
311 // Re-structure seg_digests from 16*5 to 5*16
312 for (j = 0; j < HASH_SEGS; j++) {
313 for (i = 0; i < SHA256_DIGEST_WORDS; i++) {
314 temp_buffer[i * HASH_SEGS + j] = trans_digests[j][i];
315 }
316 }
317 memcpy(digests, temp_buffer, 4 * SHA256_DIGEST_WORDS * HASH_SEGS);
318
319 return;
320 }
321
322 void mh_sha256_tail_ref(uint8_t * partial_buffer, uint32_t total_len,
323 uint32_t(*mh_sha256_segs_digests)[HASH_SEGS], uint8_t * frame_buffer,
324 uint32_t digests[SHA256_DIGEST_WORDS])
325 {
326 uint64_t partial_buffer_len, len_in_bit;
327
328 partial_buffer_len = total_len % MH_SHA256_BLOCK_SIZE;
329
330 // Padding the first block
331 partial_buffer[partial_buffer_len] = 0x80;
332 partial_buffer_len++;
333 memset(partial_buffer + partial_buffer_len, 0,
334 MH_SHA256_BLOCK_SIZE - partial_buffer_len);
335
336 // Calculate the first block without total_length if padding needs 2 block
337 if (partial_buffer_len > (MH_SHA256_BLOCK_SIZE - 8)) {
338 mh_sha256_block_ref(partial_buffer, mh_sha256_segs_digests, frame_buffer, 1);
339 //Padding the second block
340 memset(partial_buffer, 0, MH_SHA256_BLOCK_SIZE);
341 }
342 //Padding the block
343 len_in_bit = to_be64((uint64_t) total_len * 8);
344 *(uint64_t *) (partial_buffer + MH_SHA256_BLOCK_SIZE - 8) = len_in_bit;
345 mh_sha256_block_ref(partial_buffer, mh_sha256_segs_digests, frame_buffer, 1);
346
347 //Calculate multi-hash SHA256 digests (segment digests as input message)
348 sha256_for_mh_sha256_ref((uint8_t *) mh_sha256_segs_digests, digests,
349 4 * SHA256_DIGEST_WORDS * HASH_SEGS);
350
351 return;
352 }
353
354 void mh_sha256_ref(const void *buffer, uint32_t len, uint32_t * mh_sha256_digest)
355 {
356 uint64_t total_len;
357 uint64_t num_blocks;
358 uint32_t mh_sha256_segs_digests[SHA256_DIGEST_WORDS][HASH_SEGS];
359 uint8_t frame_buffer[MH_SHA256_BLOCK_SIZE];
360 uint8_t partial_block_buffer[MH_SHA256_BLOCK_SIZE * 2];
361 uint32_t mh_sha256_hash_dword[SHA256_DIGEST_WORDS];
362 uint32_t i;
363 const uint8_t *input_data = (const uint8_t *)buffer;
364
365 /* Initialize digests of all segments */
366 for (i = 0; i < HASH_SEGS; i++) {
367 mh_sha256_segs_digests[0][i] = MH_SHA256_H0;
368 mh_sha256_segs_digests[1][i] = MH_SHA256_H1;
369 mh_sha256_segs_digests[2][i] = MH_SHA256_H2;
370 mh_sha256_segs_digests[3][i] = MH_SHA256_H3;
371 mh_sha256_segs_digests[4][i] = MH_SHA256_H4;
372 mh_sha256_segs_digests[5][i] = MH_SHA256_H5;
373 mh_sha256_segs_digests[6][i] = MH_SHA256_H6;
374 mh_sha256_segs_digests[7][i] = MH_SHA256_H7;
375 }
376
377 total_len = len;
378
379 // Calculate blocks
380 num_blocks = len / MH_SHA256_BLOCK_SIZE;
381 if (num_blocks > 0) {
382 //do num_blocks process
383 mh_sha256_block_ref(input_data, mh_sha256_segs_digests, frame_buffer,
384 num_blocks);
385 len -= num_blocks * MH_SHA256_BLOCK_SIZE;
386 input_data += num_blocks * MH_SHA256_BLOCK_SIZE;
387 }
388 // Store the partial block
389 if (len != 0) {
390 memcpy(partial_block_buffer, input_data, len);
391 }
392
393 /* Finalize */
394 mh_sha256_tail_ref(partial_block_buffer, total_len, mh_sha256_segs_digests,
395 frame_buffer, mh_sha256_hash_dword);
396
397 // Output the digests of mh_sha256
398 if (mh_sha256_digest != NULL) {
399 mh_sha256_digest[0] = mh_sha256_hash_dword[0];
400 mh_sha256_digest[1] = mh_sha256_hash_dword[1];
401 mh_sha256_digest[2] = mh_sha256_hash_dword[2];
402 mh_sha256_digest[3] = mh_sha256_hash_dword[3];
403 mh_sha256_digest[4] = mh_sha256_hash_dword[4];
404 mh_sha256_digest[5] = mh_sha256_hash_dword[5];
405 mh_sha256_digest[6] = mh_sha256_hash_dword[6];
406 mh_sha256_digest[7] = mh_sha256_hash_dword[7];
407 }
408
409 return;
410 }