]>
git.proxmox.com Git - ceph.git/blob - 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.
4 Redistribution and use in source and binary forms, with or without
5 modification, are permitted provided that the following conditions
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
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.
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 **********************************************************************/
31 #include "mh_sha256_internal.h"
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 ////////////////////////////////////////////////////////////////////////
44 #define W(x) w[(x) & 15]
46 #define step(i,a,b,c,d,e,f,g,h,k) \
47 if (i<16) W(i) = to_be32(ww[i]); \
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); \
55 void sha256_single_for_mh_sha256_ref(const uint8_t * data
, uint32_t digest
[])
57 uint32_t a
, b
, c
, d
, e
, f
, g
, h
, t1
, t2
;
59 uint32_t *ww
= (uint32_t *) data
;
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);
145 void sha256_for_mh_sha256_ref(const uint8_t * input_data
, uint32_t * digest
,
149 uint8_t buf
[2 * SHA256_BLOCK_SIZE
];
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
;
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
;
167 memcpy(buf
, input_data
, i
);
169 for (j
= i
; j
< ((2 * SHA256_BLOCK_SIZE
) - 8); j
++)
172 if (i
> SHA256_BLOCK_SIZE
- 8)
173 i
= 2 * SHA256_BLOCK_SIZE
;
175 i
= SHA256_BLOCK_SIZE
;
177 *(uint64_t *) (buf
+ i
- 8) = to_be64((uint64_t) len
* 8);
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
);
185 * buffer to rearrange one segment data from one block.
187 * Layout of new_data:
189 * -------------------------
190 * w0 | w1 | ... | w15
193 static inline void transform_input_single(uint32_t * new_data
, uint32_t * input
,
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
];
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))
219 * buffer to Rearrange all segments data from one block.
221 * Layout of new_data:
223 * -------------------------
224 * seg0: | w0 | w1 | ... | w15
225 * seg1: | w0 | w1 | ... | w15
226 * seg2: | w0 | w1 | ... | w15
228 * seg15: | w0 | w1 | ... | w15
231 static inline void transform_input(uint32_t * new_data
, uint32_t * input
, uint32_t block
)
233 uint32_t *current_input
= input
+ block
* MH_SHA256_BLOCK_SIZE
/ 4;
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);
255 * buffer to Calculate all segments' digests from one block.
257 * Layout of seg_digest:
259 * -------------------------
260 * seg0: | H0 | H1 | ... | H7
261 * seg1: | H0 | H1 | ... | H7
262 * seg2: | H0 | H1 | ... | H7
264 * seg15: | H0 | H1 | ... | H7
267 static inline void sha256_update_all_segs(uint32_t * new_data
, uint32_t(*mh_sha256_seg_digests
)
268 [SHA256_DIGEST_WORDS
])
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]);
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
)
292 uint32_t *temp_buffer
= (uint32_t *) frame_buffer
;
293 uint32_t(*trans_digests
)[SHA256_DIGEST_WORDS
];
295 trans_digests
= (uint32_t(*)[SHA256_DIGEST_WORDS
]) digests
;
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
];
303 memcpy(trans_digests
, temp_buffer
, 4 * SHA256_DIGEST_WORDS
* HASH_SEGS
);
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
);
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
];
317 memcpy(digests
, temp_buffer
, 4 * SHA256_DIGEST_WORDS
* HASH_SEGS
);
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
])
326 uint64_t partial_buffer_len
, len_in_bit
;
328 partial_buffer_len
= total_len
% MH_SHA256_BLOCK_SIZE
;
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
);
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
);
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);
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
);
354 void mh_sha256_ref(const void *buffer
, uint32_t len
, uint32_t * mh_sha256_digest
)
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
];
363 const uint8_t *input_data
= (const uint8_t *)buffer
;
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
;
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
,
385 len
-= num_blocks
* MH_SHA256_BLOCK_SIZE
;
386 input_data
+= num_blocks
* MH_SHA256_BLOCK_SIZE
;
388 // Store the partial block
390 memcpy(partial_block_buffer
, input_data
, len
);
394 mh_sha256_tail_ref(partial_block_buffer
, total_len
, mh_sha256_segs_digests
,
395 frame_buffer
, mh_sha256_hash_dword
);
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];