]>
Commit | Line | Data |
---|---|---|
1e59de90 TL |
1 | /********************************************************************** |
2 | Copyright(c) 2011-2016 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 "sha256_mb.h" | |
32 | #include "memcpy_inline.h" | |
33 | #include "endian_helper.h" | |
34 | ||
35 | #ifdef _MSC_VER | |
36 | #include <intrin.h> | |
37 | #define inline __inline | |
38 | #endif | |
39 | ||
40 | #if (__GNUC__ >= 11) | |
41 | # define OPT_FIX __attribute__ ((noipa)) | |
42 | #else | |
43 | # define OPT_FIX | |
44 | #endif | |
45 | ||
46 | #define ror32(x, r) (((x)>>(r)) ^ ((x)<<(32-(r)))) | |
47 | ||
48 | #define W(x) w[(x) & 15] | |
49 | ||
50 | #define S0(w) (ror32(w,7) ^ ror32(w,18) ^ (w >> 3)) | |
51 | #define S1(w) (ror32(w,17) ^ ror32(w,19) ^ (w >> 10)) | |
52 | ||
53 | #define s0(a) (ror32(a,2) ^ ror32(a,13) ^ ror32(a,22)) | |
54 | #define s1(e) (ror32(e,6) ^ ror32(e,11) ^ ror32(e,25)) | |
55 | #define maj(a,b,c) ((a & b) ^ (a & c) ^ (b & c)) | |
56 | #define ch(e,f,g) ((e & f) ^ (g & ~e)) | |
57 | ||
58 | #define step(i,a,b,c,d,e,f,g,h,k) \ | |
59 | if (i<16) W(i) = to_be32(ww[i]); \ | |
60 | else \ | |
61 | W(i) = W(i-16) + S0(W(i-15)) + W(i-7) + S1(W(i-2)); \ | |
62 | t2 = s0(a) + maj(a,b,c); \ | |
63 | t1 = h + s1(e) + ch(e,f,g) + k + W(i); \ | |
64 | d += t1; \ | |
65 | h = t1 + t2; | |
66 | ||
67 | static void sha256_init(SHA256_HASH_CTX * ctx, const void *buffer, uint32_t len); | |
68 | static uint32_t sha256_update(SHA256_HASH_CTX * ctx, const void *buffer, uint32_t len); | |
69 | static void sha256_final(SHA256_HASH_CTX * ctx, uint32_t remain_len); | |
70 | static void OPT_FIX sha256_single(const void *data, uint32_t digest[]); | |
71 | static inline void hash_init_digest(SHA256_WORD_T * digest); | |
72 | ||
73 | void sha256_ctx_mgr_init_base(SHA256_HASH_CTX_MGR * mgr) | |
74 | { | |
75 | } | |
76 | ||
77 | SHA256_HASH_CTX *sha256_ctx_mgr_submit_base(SHA256_HASH_CTX_MGR * mgr, SHA256_HASH_CTX * ctx, | |
78 | const void *buffer, uint32_t len, | |
79 | HASH_CTX_FLAG flags) | |
80 | { | |
81 | uint32_t remain_len; | |
82 | ||
83 | if (flags & (~HASH_ENTIRE)) { | |
84 | // User should not pass anything other than FIRST, UPDATE, or LAST | |
85 | ctx->error = HASH_CTX_ERROR_INVALID_FLAGS; | |
86 | return ctx; | |
87 | } | |
88 | ||
89 | if ((ctx->status & HASH_CTX_STS_PROCESSING) && (flags == HASH_ENTIRE)) { | |
90 | // Cannot submit a new entire job to a currently processing job. | |
91 | ctx->error = HASH_CTX_ERROR_ALREADY_PROCESSING; | |
92 | return ctx; | |
93 | } | |
94 | ||
95 | if ((ctx->status & HASH_CTX_STS_COMPLETE) && !(flags & HASH_FIRST)) { | |
96 | // Cannot update a finished job. | |
97 | ctx->error = HASH_CTX_ERROR_ALREADY_COMPLETED; | |
98 | return ctx; | |
99 | } | |
100 | ||
101 | if (flags == HASH_FIRST) { | |
102 | ||
103 | sha256_init(ctx, buffer, len); | |
104 | sha256_update(ctx, buffer, len); | |
105 | } | |
106 | ||
107 | if (flags == HASH_UPDATE) { | |
108 | sha256_update(ctx, buffer, len); | |
109 | } | |
110 | ||
111 | if (flags == HASH_LAST) { | |
112 | remain_len = sha256_update(ctx, buffer, len); | |
113 | sha256_final(ctx, remain_len); | |
114 | } | |
115 | ||
116 | if (flags == HASH_ENTIRE) { | |
117 | sha256_init(ctx, buffer, len); | |
118 | remain_len = sha256_update(ctx, buffer, len); | |
119 | sha256_final(ctx, remain_len); | |
120 | } | |
121 | ||
122 | return ctx; | |
123 | } | |
124 | ||
125 | SHA256_HASH_CTX *sha256_ctx_mgr_flush_base(SHA256_HASH_CTX_MGR * mgr) | |
126 | { | |
127 | return NULL; | |
128 | } | |
129 | ||
130 | static void sha256_init(SHA256_HASH_CTX * ctx, const void *buffer, uint32_t len) | |
131 | { | |
132 | // Init digest | |
133 | hash_init_digest(ctx->job.result_digest); | |
134 | ||
135 | // Reset byte counter | |
136 | ctx->total_length = 0; | |
137 | ||
138 | // Clear extra blocks | |
139 | ctx->partial_block_buffer_length = 0; | |
140 | ||
141 | // If we made it here, there were no errors during this call to submit | |
142 | ctx->error = HASH_CTX_ERROR_NONE; | |
143 | ||
144 | // Mark it as processing | |
145 | ctx->status = HASH_CTX_STS_PROCESSING; | |
146 | } | |
147 | ||
148 | static uint32_t sha256_update(SHA256_HASH_CTX * ctx, const void *buffer, uint32_t len) | |
149 | { | |
150 | uint32_t remain_len = len; | |
151 | uint32_t *digest = ctx->job.result_digest; | |
152 | ||
153 | while (remain_len >= SHA256_BLOCK_SIZE) { | |
154 | sha256_single(buffer, digest); | |
155 | buffer = (void *)((uint8_t *) buffer + SHA256_BLOCK_SIZE); | |
156 | remain_len -= SHA256_BLOCK_SIZE; | |
157 | ctx->total_length += SHA256_BLOCK_SIZE; | |
158 | } | |
159 | ctx->status = HASH_CTX_STS_IDLE; | |
160 | ctx->incoming_buffer = buffer; | |
161 | return remain_len; | |
162 | } | |
163 | ||
164 | static void sha256_final(SHA256_HASH_CTX * ctx, uint32_t remain_len) | |
165 | { | |
166 | const void *buffer = ctx->incoming_buffer; | |
167 | uint32_t i = remain_len, j; | |
168 | uint8_t buf[2 * SHA256_BLOCK_SIZE]; | |
169 | uint32_t *digest = ctx->job.result_digest; | |
170 | ||
171 | ctx->total_length += i; | |
172 | memcpy(buf, buffer, i); | |
173 | buf[i++] = 0x80; | |
174 | for (j = i; j < ((2 * SHA256_BLOCK_SIZE) - SHA256_PADLENGTHFIELD_SIZE); j++) | |
175 | buf[j] = 0; | |
176 | ||
177 | if (i > SHA256_BLOCK_SIZE - SHA256_PADLENGTHFIELD_SIZE) | |
178 | i = 2 * SHA256_BLOCK_SIZE; | |
179 | else | |
180 | i = SHA256_BLOCK_SIZE; | |
181 | ||
182 | *(uint64_t *) (buf + i - 8) = to_be64((uint64_t) ctx->total_length * 8); | |
183 | ||
184 | sha256_single(buf, digest); | |
185 | if (i == 2 * SHA256_BLOCK_SIZE) { | |
186 | sha256_single(buf + SHA256_BLOCK_SIZE, digest); | |
187 | } | |
188 | ||
189 | ctx->status = HASH_CTX_STS_COMPLETE; | |
190 | } | |
191 | ||
192 | void sha256_single(const void *data, uint32_t digest[]) | |
193 | { | |
194 | uint32_t a, b, c, d, e, f, g, h, t1, t2; | |
195 | uint32_t w[16]; | |
196 | uint32_t *ww = (uint32_t *) data; | |
197 | ||
198 | a = digest[0]; | |
199 | b = digest[1]; | |
200 | c = digest[2]; | |
201 | d = digest[3]; | |
202 | e = digest[4]; | |
203 | f = digest[5]; | |
204 | g = digest[6]; | |
205 | h = digest[7]; | |
206 | ||
207 | step(0, a, b, c, d, e, f, g, h, 0x428a2f98); | |
208 | step(1, h, a, b, c, d, e, f, g, 0x71374491); | |
209 | step(2, g, h, a, b, c, d, e, f, 0xb5c0fbcf); | |
210 | step(3, f, g, h, a, b, c, d, e, 0xe9b5dba5); | |
211 | step(4, e, f, g, h, a, b, c, d, 0x3956c25b); | |
212 | step(5, d, e, f, g, h, a, b, c, 0x59f111f1); | |
213 | step(6, c, d, e, f, g, h, a, b, 0x923f82a4); | |
214 | step(7, b, c, d, e, f, g, h, a, 0xab1c5ed5); | |
215 | step(8, a, b, c, d, e, f, g, h, 0xd807aa98); | |
216 | step(9, h, a, b, c, d, e, f, g, 0x12835b01); | |
217 | step(10, g, h, a, b, c, d, e, f, 0x243185be); | |
218 | step(11, f, g, h, a, b, c, d, e, 0x550c7dc3); | |
219 | step(12, e, f, g, h, a, b, c, d, 0x72be5d74); | |
220 | step(13, d, e, f, g, h, a, b, c, 0x80deb1fe); | |
221 | step(14, c, d, e, f, g, h, a, b, 0x9bdc06a7); | |
222 | step(15, b, c, d, e, f, g, h, a, 0xc19bf174); | |
223 | step(16, a, b, c, d, e, f, g, h, 0xe49b69c1); | |
224 | step(17, h, a, b, c, d, e, f, g, 0xefbe4786); | |
225 | step(18, g, h, a, b, c, d, e, f, 0x0fc19dc6); | |
226 | step(19, f, g, h, a, b, c, d, e, 0x240ca1cc); | |
227 | step(20, e, f, g, h, a, b, c, d, 0x2de92c6f); | |
228 | step(21, d, e, f, g, h, a, b, c, 0x4a7484aa); | |
229 | step(22, c, d, e, f, g, h, a, b, 0x5cb0a9dc); | |
230 | step(23, b, c, d, e, f, g, h, a, 0x76f988da); | |
231 | step(24, a, b, c, d, e, f, g, h, 0x983e5152); | |
232 | step(25, h, a, b, c, d, e, f, g, 0xa831c66d); | |
233 | step(26, g, h, a, b, c, d, e, f, 0xb00327c8); | |
234 | step(27, f, g, h, a, b, c, d, e, 0xbf597fc7); | |
235 | step(28, e, f, g, h, a, b, c, d, 0xc6e00bf3); | |
236 | step(29, d, e, f, g, h, a, b, c, 0xd5a79147); | |
237 | step(30, c, d, e, f, g, h, a, b, 0x06ca6351); | |
238 | step(31, b, c, d, e, f, g, h, a, 0x14292967); | |
239 | step(32, a, b, c, d, e, f, g, h, 0x27b70a85); | |
240 | step(33, h, a, b, c, d, e, f, g, 0x2e1b2138); | |
241 | step(34, g, h, a, b, c, d, e, f, 0x4d2c6dfc); | |
242 | step(35, f, g, h, a, b, c, d, e, 0x53380d13); | |
243 | step(36, e, f, g, h, a, b, c, d, 0x650a7354); | |
244 | step(37, d, e, f, g, h, a, b, c, 0x766a0abb); | |
245 | step(38, c, d, e, f, g, h, a, b, 0x81c2c92e); | |
246 | step(39, b, c, d, e, f, g, h, a, 0x92722c85); | |
247 | step(40, a, b, c, d, e, f, g, h, 0xa2bfe8a1); | |
248 | step(41, h, a, b, c, d, e, f, g, 0xa81a664b); | |
249 | step(42, g, h, a, b, c, d, e, f, 0xc24b8b70); | |
250 | step(43, f, g, h, a, b, c, d, e, 0xc76c51a3); | |
251 | step(44, e, f, g, h, a, b, c, d, 0xd192e819); | |
252 | step(45, d, e, f, g, h, a, b, c, 0xd6990624); | |
253 | step(46, c, d, e, f, g, h, a, b, 0xf40e3585); | |
254 | step(47, b, c, d, e, f, g, h, a, 0x106aa070); | |
255 | step(48, a, b, c, d, e, f, g, h, 0x19a4c116); | |
256 | step(49, h, a, b, c, d, e, f, g, 0x1e376c08); | |
257 | step(50, g, h, a, b, c, d, e, f, 0x2748774c); | |
258 | step(51, f, g, h, a, b, c, d, e, 0x34b0bcb5); | |
259 | step(52, e, f, g, h, a, b, c, d, 0x391c0cb3); | |
260 | step(53, d, e, f, g, h, a, b, c, 0x4ed8aa4a); | |
261 | step(54, c, d, e, f, g, h, a, b, 0x5b9cca4f); | |
262 | step(55, b, c, d, e, f, g, h, a, 0x682e6ff3); | |
263 | step(56, a, b, c, d, e, f, g, h, 0x748f82ee); | |
264 | step(57, h, a, b, c, d, e, f, g, 0x78a5636f); | |
265 | step(58, g, h, a, b, c, d, e, f, 0x84c87814); | |
266 | step(59, f, g, h, a, b, c, d, e, 0x8cc70208); | |
267 | step(60, e, f, g, h, a, b, c, d, 0x90befffa); | |
268 | step(61, d, e, f, g, h, a, b, c, 0xa4506ceb); | |
269 | step(62, c, d, e, f, g, h, a, b, 0xbef9a3f7); | |
270 | step(63, b, c, d, e, f, g, h, a, 0xc67178f2); | |
271 | ||
272 | digest[0] += a; | |
273 | digest[1] += b; | |
274 | digest[2] += c; | |
275 | digest[3] += d; | |
276 | digest[4] += e; | |
277 | digest[5] += f; | |
278 | digest[6] += g; | |
279 | digest[7] += h; | |
280 | } | |
281 | ||
282 | static inline void hash_init_digest(SHA256_WORD_T * digest) | |
283 | { | |
284 | static const SHA256_WORD_T hash_initial_digest[SHA256_DIGEST_NWORDS] = | |
285 | { SHA256_INITIAL_DIGEST }; | |
286 | memcpy_fixedlen(digest, hash_initial_digest, sizeof(hash_initial_digest)); | |
287 | } | |
288 | ||
289 | struct slver { | |
290 | uint16_t snum; | |
291 | uint8_t ver; | |
292 | uint8_t core; | |
293 | }; | |
294 | struct slver sha256_ctx_mgr_init_base_slver_000002f0; | |
295 | struct slver sha256_ctx_mgr_init_base_slver = { 0x02f0, 0x00, 0x00 }; | |
296 | ||
297 | struct slver sha256_ctx_mgr_submit_base_slver_000002f1; | |
298 | struct slver sha256_ctx_mgr_submit_base_slver = { 0x02f1, 0x00, 0x00 }; | |
299 | ||
300 | struct slver sha256_ctx_mgr_flush_base_slver_000002f2; | |
301 | struct slver sha256_ctx_mgr_flush_base_slver = { 0x02f2, 0x00, 0x00 }; |