xref: /isa-l_crypto/mh_sha256/mh_sha256_ref.c (revision e3f7d4fb1bd3dcbfb75b87e0c61870e751d613aa)
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 }
411