]>
git.proxmox.com Git - ceph.git/blob - 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.
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_sha1_internal.h"
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 ////////////////////////////////////////////////////////////////////////
44 #define W(x) w[(x) & 15]
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); \
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); \
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); \
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); \
67 void sha1_single_for_mh_sha1_ref(const uint8_t * data
, uint32_t digest
[])
69 uint32_t a
, b
, c
, d
, e
;
70 uint32_t w
[16] = { 0 };
71 uint32_t *ww
= (uint32_t *) data
;
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
);
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
);
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
);
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
);
170 void sha1_for_mh_sha1_ref(const uint8_t * input_data
, uint32_t * digest
, const uint32_t len
)
173 uint8_t buf
[2 * SHA1_BLOCK_SIZE
];
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
;
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
;
193 memcpy(buf
, input_data
, i
);
195 for (j
= i
; j
< ((2 * SHA1_BLOCK_SIZE
) - 8); j
++)
198 if (i
> SHA1_BLOCK_SIZE
- 8)
199 i
= 2 * SHA1_BLOCK_SIZE
;
203 convert
.uint
= 8 * len
;
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];
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
);
220 * buffer to rearrange one segment data from one block.
222 * Layout of new_data:
224 * -------------------------
225 * w0 | w1 | ... | w15
228 static inline void transform_input_single(uint32_t * new_data
, uint32_t * input
,
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
];
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))
254 * buffer to Rearrange all segments data from one block.
256 * Layout of new_data:
258 * -------------------------
259 * seg0: | w0 | w1 | ... | w15
260 * seg1: | w0 | w1 | ... | w15
261 * seg2: | w0 | w1 | ... | w15
263 * seg15: | w0 | w1 | ... | w15
266 static inline void transform_input(uint32_t * new_data
, uint32_t * input
, uint32_t block
)
268 uint32_t *current_input
= input
+ block
* MH_SHA1_BLOCK_SIZE
/ 4;
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);
290 * buffer to Calculate all segments' digests from one block.
292 * Layout of seg_digest:
294 * -------------------------
295 * seg0: | H0 | H1 | ... | H4
296 * seg1: | H0 | H1 | ... | H4
297 * seg2: | H0 | H1 | ... | H4
299 * seg15: | H0 | H1 | ... | H4
302 static inline void sha1_update_all_segs(uint32_t * new_data
,
303 uint32_t(*mh_sha1_seg_digests
)[SHA1_DIGEST_WORDS
])
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]);
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
)
327 uint32_t *temp_buffer
= (uint32_t *) frame_buffer
;
328 uint32_t(*trans_digests
)[SHA1_DIGEST_WORDS
];
330 trans_digests
= (uint32_t(*)[SHA1_DIGEST_WORDS
]) digests
;
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
];
338 memcpy(trans_digests
, temp_buffer
, 4 * SHA1_DIGEST_WORDS
* HASH_SEGS
);
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
);
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
];
352 memcpy(digests
, temp_buffer
, 4 * SHA1_DIGEST_WORDS
* HASH_SEGS
);
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
])
361 uint64_t partial_buffer_len
, len_in_bit
;
363 partial_buffer_len
= total_len
% MH_SHA1_BLOCK_SIZE
;
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
);
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
);
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);
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
);
389 void mh_sha1_ref(const void *buffer
, uint32_t len
, uint32_t * mh_sha1_digest
)
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
];
398 const uint8_t *input_data
= (const uint8_t *)buffer
;
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
;
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
;
419 // Store the partial block
421 memcpy(partial_block_buffer
, input_data
, len
);
425 mh_sha1_tail_ref(partial_block_buffer
, total_len
, mh_sha1_segs_digests
,
426 frame_buffer
, mh_sha1_hash_dword
);
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];