xref: /isa-l_crypto/mh_sha256/mh_sha256_block_base.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 "mh_sha256_internal.h"
31 #include <string.h>
32 
33 ////////////////////////////////////////////////////////////////////////
34 ////////////////////////////////////////////////////////////////////////
35 // Base multi-hash SHA256 Functions
36 ////////////////////////////////////////////////////////////////////////
37 ////////////////////////////////////////////////////////////////////////
38 // store_w is only used for step 0 ~ 15
39 #define store_w(s, i, w, ww) (w[i][s] = to_be32(ww[i*HASH_SEGS+s]))
40 #define Ws(x, s) w[(x) & 15][s]
41 // update_w is used for step > 15
42 #define update_w(s, i, w) \
43 	Ws(i, s) = Ws(i-16, s) + S0(Ws(i-15, s)) + Ws(i-7, s) + S1(Ws(i-2, s))
44 #define update_t2(s, a, b, c) t2[s] = s0(a[s]) + maj(a[s],b[s],c[s])
45 #define update_t1(s, h, e, f, g, i, k) \
46 	t1[s] = h[s] + s1(e[s]) + ch(e[s],f[s],g[s]) + k + Ws(i, s);
47 #define update_d(s) d[s] += t1[s]
48 #define update_h(s) h[s] = t1[s] + t2[s]
49 
50 // s is a iterator
51 #define STORE_W(s, i, w, ww) \
52 	for(s = 0; s < HASH_SEGS; s++) \
53 		store_w(s, i, w, ww);
54 #define UPDATE_W(s, i, w) \
55 	for(s = 0; s < HASH_SEGS; s++) \
56 		update_w(s, i, w);
57 #define UPDATE_T2(s, a, b, c) \
58 	for(s = 0; s < HASH_SEGS; s++) \
59 		update_t2(s, a, b, c);
60 #define UPDATE_T1(s, h, e, f, g, i, k) \
61 	for(s = 0; s < HASH_SEGS; s++) \
62 		update_t1(s, h, e, f, g, i, k);
63 #define UPDATE_D(s) \
64 	for(s = 0; s < HASH_SEGS; s++) \
65 		update_d(s);
66 #define UPDATE_H(s) \
67 	for(s = 0; s < HASH_SEGS; s++) \
68 		update_h(s);
69 
70 static inline void step(int i, uint32_t * a, uint32_t * b, uint32_t * c,
71 			uint32_t * d, uint32_t * e, uint32_t * f,
72 			uint32_t * g, uint32_t * h, uint32_t k,
73 			uint32_t * t1, uint32_t * t2, uint32_t(*w)[HASH_SEGS], uint32_t * ww)
74 {
75 	uint8_t s;
76 	if (i < 16) {
77 		STORE_W(s, i, w, ww);
78 	} else {
79 		UPDATE_W(s, i, w);
80 	}
81 	UPDATE_T2(s, a, b, c);
82 	UPDATE_T1(s, h, e, f, g, i, k);
83 	UPDATE_D(s);
84 	UPDATE_H(s);
85 }
86 
87 static inline void init_abcdefgh(uint32_t * xx, uint32_t n,
88 				 uint32_t digests[SHA256_DIGEST_WORDS][HASH_SEGS])
89 {
90 	uint8_t s;
91 	for (s = 0; s < HASH_SEGS; s++)
92 		xx[s] = digests[n][s];
93 }
94 
95 static inline void add_abcdefgh(uint32_t * xx, uint32_t n,
96 				uint32_t digests[SHA256_DIGEST_WORDS][HASH_SEGS])
97 {
98 	uint8_t s;
99 	for (s = 0; s < HASH_SEGS; s++)
100 		digests[n][s] += xx[s];
101 }
102 
103 /*
104  * API to perform 0-64 steps of the multi-hash algorithm for
105  * a single block of data. The caller is responsible for ensuring
106  * a full block of data input.
107  *
108  * Argument:
109  *   input  - the pointer to the data
110  *   digest - the space to hold the digests for all segments.
111  *
112  * Return:
113  *   N/A
114  */
115 void mh_sha256_single(const uint8_t * input, uint32_t(*digests)[HASH_SEGS],
116 		      uint8_t * frame_buffer)
117 {
118 	uint8_t i;
119 	uint32_t aa[HASH_SEGS], bb[HASH_SEGS], cc[HASH_SEGS], dd[HASH_SEGS];
120 	uint32_t ee[HASH_SEGS], ff[HASH_SEGS], gg[HASH_SEGS], hh[HASH_SEGS];
121 	uint32_t t1[HASH_SEGS], t2[HASH_SEGS];
122 	uint32_t *ww = (uint32_t *) input;
123 	uint32_t(*w)[HASH_SEGS];
124 
125 	const static uint32_t k[64] = {
126 		0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,
127 		0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
128 		0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
129 		0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
130 		0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,
131 		0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
132 		0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7,
133 		0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
134 		0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
135 		0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
136 		0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3,
137 		0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
138 		0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5,
139 		0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
140 		0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
141 		0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
142 	};
143 
144 	w = (uint32_t(*)[HASH_SEGS]) frame_buffer;
145 
146 	init_abcdefgh(aa, 0, digests);
147 	init_abcdefgh(bb, 1, digests);
148 	init_abcdefgh(cc, 2, digests);
149 	init_abcdefgh(dd, 3, digests);
150 	init_abcdefgh(ee, 4, digests);
151 	init_abcdefgh(ff, 5, digests);
152 	init_abcdefgh(gg, 6, digests);
153 	init_abcdefgh(hh, 7, digests);
154 
155 	for (i = 0; i < 64; i += 8) {
156 		step(i, aa, bb, cc, dd, ee, ff, gg, hh, k[i], t1, t2, w, ww);
157 		step(i + 1, hh, aa, bb, cc, dd, ee, ff, gg, k[i + 1], t1, t2, w, ww);
158 		step(i + 2, gg, hh, aa, bb, cc, dd, ee, ff, k[i + 2], t1, t2, w, ww);
159 		step(i + 3, ff, gg, hh, aa, bb, cc, dd, ee, k[i + 3], t1, t2, w, ww);
160 		step(i + 4, ee, ff, gg, hh, aa, bb, cc, dd, k[i + 4], t1, t2, w, ww);
161 		step(i + 5, dd, ee, ff, gg, hh, aa, bb, cc, k[i + 5], t1, t2, w, ww);
162 		step(i + 6, cc, dd, ee, ff, gg, hh, aa, bb, k[i + 6], t1, t2, w, ww);
163 		step(i + 7, bb, cc, dd, ee, ff, gg, hh, aa, k[i + 7], t1, t2, w, ww);
164 	}
165 
166 	add_abcdefgh(aa, 0, digests);
167 	add_abcdefgh(bb, 1, digests);
168 	add_abcdefgh(cc, 2, digests);
169 	add_abcdefgh(dd, 3, digests);
170 	add_abcdefgh(ee, 4, digests);
171 	add_abcdefgh(ff, 5, digests);
172 	add_abcdefgh(gg, 6, digests);
173 	add_abcdefgh(hh, 7, digests);
174 }
175 
176 void mh_sha256_block_base(const uint8_t * input_data,
177 			  uint32_t digests[SHA256_DIGEST_WORDS][HASH_SEGS],
178 			  uint8_t frame_buffer[MH_SHA256_BLOCK_SIZE], uint32_t num_blocks)
179 {
180 	uint32_t i;
181 
182 	for (i = 0; i < num_blocks; i++) {
183 		mh_sha256_single(input_data, digests, frame_buffer);
184 		input_data += MH_SHA256_BLOCK_SIZE;
185 	}
186 
187 	return;
188 }
189